This is the code for the statistical analysis for “Vowel Acoustics as Predictors of Speech Intelligibility in Dysarthria.”
Loading Packages
library(rio)
library(tidyverse)
library(irr) # install.packages('irr')
library(performance)
library(car)
library(ggpubr)
library("Hmisc") # install.packages('Hmisc')
library(ggridges)
library(furniture) # install.packages('furniture')
library(gt)
library(patchwork)
library(ks)
library(emuR) # install.packages('emuR')
library(geomtextpath) # remotes::install_github("AllanCameron/geomtextpath")
Upload Datasets
Reliability <- rio::import("Prepped Data/Reliability Data.csv")
AcousticData <- rio::import("Prepped Data/AcousticMeasures.csv") %>%
dplyr::mutate(intDiff = VAS - transAcc)
AcousticData <- AcousticData %>%
dplyr::filter(!grepl("_rel", Speaker)) %>%
dplyr::select(c(Speaker, Sex, Etiology, vowel_ED_b, VSA_b, Hull_b, Hull_bVSD_25, Hull_bVSD_50, Hull_bVSD_75, VAS, transAcc)) %>%
dplyr::mutate(Etiology = as.factor(Etiology),
Sex = as.factor(Sex),
Speaker = as.factor(Speaker))
Listeners <- rio::import("Prepped Data/Listener_Demographics.csv") %>%
dplyr::select(!c(StartDate:proloficID, Q2.4_6_TEXT, Q3.2_8_TEXT, AudioCheck:EP3))
Listeners$race[Listeners$Q3.3_7_TEXT == "Native American/ African amercing"] <- "Biracial or Multiracial"
Inter-rater Reliability
Two raters (the first two authors) completed vowel segmentation for the speakers. To calculate inter-rater reliability, 20% of the speakers were segmented again by the other rater. Two-way intraclass coefficients were computed for the extracted F1 and F2 from the temporal midpoint of the vowel segments. Since only one set of ratings will be used in the data analysis, we focus on the single ICC results and interpretation. However, we also report the average ICC values to be comprehensive.
## Creating new data frames to calculate ICC for extracted F1 and F2 values
F1_Rel <- Reliability %>%
dplyr::select(c(F1, F1_rel))
F2_Rel <- Reliability %>%
dplyr::select(c(F2, F2_rel))
## Single ICC for F1
Single_F1 <- irr::icc(F1_Rel, model = "twoway", type = "agreement", unit = "single")
## Average ICC for F1
Average_F1 <- irr::icc(F1_Rel, model = "twoway", type = "agreement", unit = "average")
## Single ICC for F2
Single_F2 <- irr::icc(F2_Rel, model = "twoway", type = "agreement", unit = "single")
## Average ICC for F2
Average_F2 <- irr::icc(F2_Rel, model = "twoway", type = "agreement", unit = "average")
## Inter-rater reliability results and interpretation
print(paste("Single ICC for F1 is ", round(Single_F1$value, digits = 3), ". ",
"The 95% CI is [", round(Single_F1$lbound, digits = 3), " - ", round(Single_F1$ubound, digits = 3), "].", sep = ""))
[1] "Single ICC for F1 is 0.866. The 95% CI is [0.837 - 0.89]."
print(paste("Single ICC for F2 is ", round(Single_F2$value, digits = 3), ". ",
"The 95% CI is [", round(Single_F2$lbound, digits = 3), " - ", round(Single_F2$ubound, digits = 3), "].", sep = ""))
[1] "Single ICC for F2 is 0.931. The 95% CI is [0.916 - 0.944]."
print(paste("Average ICC for F1 is ", round(Average_F1$value, digits = 3), ". ",
"The 95% CI is [", round(Average_F1$lbound, digits = 3), " - ", round(Average_F1$ubound, digits = 3), "].", sep = ""))
[1] "Average ICC for F1 is 0.928. The 95% CI is [0.911 - 0.942]."
print(paste("Average ICC for F2 is ", round(Average_F2$value, digits = 3), ". ",
"The 95% CI is [", round(Average_F2$lbound, digits = 3), " - ", round(Average_F2$ubound, digits = 3), "].", sep = ""))
[1] "Average ICC for F2 is 0.964. The 95% CI is [0.956 - 0.971]."
print("Thus, interrater reliability for the extracted F1 and F2 values from the vowel segments was good to excellent.")
[1] "Thus, interrater reliability for the extracted F1 and F2 values from the vowel segments was good to excellent."
## Removing extra data frames from environment
rm(F1_Rel, F2_Rel, Reliability, Single_F1, Single_F2, Average_F1, Average_F2)
Descriptive Statistics
Correlations
CorrMatrix <- AcousticData %>%
dplyr::select(VSA_b, vowel_ED_b, Hull_b, Hull_bVSD_25, Hull_bVSD_50, Hull_bVSD_75, VAS, transAcc) %>%
as.matrix() %>%
Hmisc::rcorr()
CorrMatrix <- CorrMatrix$r
stats::cor.test(AcousticData$VSA_b, AcousticData$vowel_ED_b, method = "pearson")
Pearson's product-moment correlation
data: AcousticData$VSA_b and AcousticData$vowel_ED_b
t = 6.5285, df = 38, p-value = 1.076e-07
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.5372669 0.8468014
sample estimates:
cor
0.7270881
stats::cor.test(AcousticData$Hull_b, AcousticData$Hull_bVSD_25, method = "pearson")
Pearson's product-moment correlation
data: AcousticData$Hull_b and AcousticData$Hull_bVSD_25
t = 9.4906, df = 38, p-value = 1.43e-11
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.7135136 0.9119080
sample estimates:
cor
0.838625
write.csv(CorrMatrix, file = "Tables/Correlation Matrix.csv")
rm(CorrMatrix)
Research Q1: Modeling Intelligibility
Orthographic Transcriptions
Model 1
# Specifying Model 1
OT_Model1 <- lm(transAcc ~ Hull_bVSD_25, data = AcousticData)
## Model 1 Assumptions
performance::check_model(OT_Model1)

## Model 1 Summary
summary(OT_Model1)
Call:
lm(formula = transAcc ~ Hull_bVSD_25, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-47.896 -14.090 5.996 17.470 36.105
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 48.2973 9.7372 4.960 1.5e-05 ***
Hull_bVSD_25 0.6417 0.5663 1.133 0.264
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 23.83 on 38 degrees of freedom
Multiple R-squared: 0.03268, Adjusted R-squared: 0.007224
F-statistic: 1.284 on 1 and 38 DF, p-value: 0.2643
Model 2
## Specifying Model 2
OT_Model2 <- lm(transAcc ~ Hull_bVSD_25 + Hull_bVSD_75, data = AcousticData)
## Model 2 Assumption Check
performance::check_model(OT_Model2)

## Model 2 Summary
summary(OT_Model2)
Call:
lm(formula = transAcc ~ Hull_bVSD_25 + Hull_bVSD_75, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-48.854 -13.962 5.567 16.758 36.257
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 47.3374 10.3316 4.582 5.09e-05 ***
Hull_bVSD_25 0.8045 0.7781 1.034 0.308
Hull_bVSD_75 -0.7188 2.3225 -0.309 0.759
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 24.11 on 37 degrees of freedom
Multiple R-squared: 0.03518, Adjusted R-squared: -0.01698
F-statistic: 0.6745 on 2 and 37 DF, p-value: 0.5156
## Model 1 and Model 2 Comparison
anova(OT_Model1, OT_Model2)
Analysis of Variance Table
Model 1: transAcc ~ Hull_bVSD_25
Model 2: transAcc ~ Hull_bVSD_25 + Hull_bVSD_75
Res.Df RSS Df Sum of Sq F Pr(>F)
1 38 21570
2 37 21514 1 55.696 0.0958 0.7587
Model 3
## Specifying Model 3
OT_Model3 <- lm(transAcc ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b, data = AcousticData)
## Model 3 Assumption Check
performance::check_model(OT_Model3)

## Model 3 Summary
summary(OT_Model3)
Call:
lm(formula = transAcc ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b,
data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-56.706 -13.157 7.018 17.957 29.990
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 31.0806 14.4916 2.145 0.0388 *
Hull_bVSD_25 -0.8439 1.2984 -0.650 0.5199
Hull_bVSD_75 0.3159 2.3714 0.133 0.8948
Hull_b 1.2941 0.8247 1.569 0.1253
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 23.65 on 36 degrees of freedom
Multiple R-squared: 0.09695, Adjusted R-squared: 0.0217
F-statistic: 1.288 on 3 and 36 DF, p-value: 0.2932
## Model 2 and Model 3 Comparison
anova(OT_Model2, OT_Model3)
Analysis of Variance Table
Model 1: transAcc ~ Hull_bVSD_25 + Hull_bVSD_75
Model 2: transAcc ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b
Res.Df RSS Df Sum of Sq F Pr(>F)
1 37 21514
2 36 20137 1 1377.5 2.4626 0.1253
Model 4
## Specifying Model 4
OT_Model4 <- lm(transAcc ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b, data = AcousticData)
## Model 4 Assumption Check
performance::check_model(OT_Model4)

## Model 4 Summary
summary(OT_Model4)
Call:
lm(formula = transAcc ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b +
VSA_b, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-44.796 -11.144 3.042 12.567 34.297
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 27.4533 13.1156 2.093 0.04365 *
Hull_bVSD_25 -1.2602 1.1782 -1.070 0.29214
Hull_bVSD_75 0.5663 2.1390 0.265 0.79274
Hull_b 0.7364 0.7654 0.962 0.34261
VSA_b 6.0896 1.9954 3.052 0.00432 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 21.32 on 35 degrees of freedom
Multiple R-squared: 0.2868, Adjusted R-squared: 0.2052
F-statistic: 3.518 on 4 and 35 DF, p-value: 0.01626
## Model 3 and Model 4 Comparison
anova(OT_Model3, OT_Model4)
Analysis of Variance Table
Model 1: transAcc ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b
Model 2: transAcc ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b
Res.Df RSS Df Sum of Sq F Pr(>F)
1 36 20137
2 35 15904 1 4232.4 9.314 0.004321 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Model 5
## Specifying Model 5
OT_Model5 <- lm(transAcc ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b + vowel_ED_b, data = AcousticData)
## Model 4 Assumption Check
performance::check_model(OT_Model5)

## Model 4 Summary
summary(OT_Model5)
Call:
lm(formula = transAcc ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b +
VSA_b + vowel_ED_b, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-46.533 -11.028 3.327 13.017 33.227
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 20.3598 21.5072 0.947 0.3505
Hull_bVSD_25 -1.2567 1.1924 -1.054 0.2994
Hull_bVSD_75 0.7007 2.1882 0.320 0.7508
Hull_b 0.6895 0.7826 0.881 0.3845
VSA_b 5.3903 2.6194 2.058 0.0473 *
vowel_ED_b 5.5182 13.1650 0.419 0.6777
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 21.57 on 34 degrees of freedom
Multiple R-squared: 0.2904, Adjusted R-squared: 0.1861
F-statistic: 2.783 on 5 and 34 DF, p-value: 0.03271
## Model 3 and Model 4 Comparison
anova(OT_Model4, OT_Model5)
Analysis of Variance Table
Model 1: transAcc ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b
Model 2: transAcc ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b + vowel_ED_b
Res.Df RSS Df Sum of Sq F Pr(>F)
1 35 15904
2 34 15823 1 81.764 0.1757 0.6777
Final Model
## Specifying Final Model
OT_Model_final <- lm(transAcc ~ VSA_b, data = AcousticData)
## Final Model Assumption Check
performance::check_model(OT_Model_final)

## Final Model Summary
summary(OT_Model_final)
Call:
lm(formula = transAcc ~ VSA_b, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-46.72 -12.69 2.97 14.37 35.39
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 32.508 7.857 4.138 0.000187 ***
VSA_b 5.872 1.613 3.641 0.000807 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 20.86 on 38 degrees of freedom
Multiple R-squared: 0.2586, Adjusted R-squared: 0.2391
F-statistic: 13.25 on 1 and 38 DF, p-value: 0.0008068
confint(OT_Model_final)
2.5 % 97.5 %
(Intercept) 16.602765 48.413532
VSA_b 2.606927 9.137097
VAS Models
Model 1
# Specifying Model 1
VAS_Model1 <- lm(VAS ~ Hull_bVSD_25, data = AcousticData)
## Model 1 Assumptions
performance::check_model(VAS_Model1)

## Model 1 Summary
summary(VAS_Model1)
Call:
lm(formula = VAS ~ Hull_bVSD_25, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-47.625 -16.684 8.462 19.440 37.352
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 42.6328 10.7512 3.965 0.000313 ***
Hull_bVSD_25 0.5877 0.6253 0.940 0.353236
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 26.31 on 38 degrees of freedom
Multiple R-squared: 0.02272, Adjusted R-squared: -0.003001
F-statistic: 0.8833 on 1 and 38 DF, p-value: 0.3532
Model 2
## Specifying Model 2
VAS_Model2 <- lm(VAS ~ Hull_bVSD_25 + Hull_bVSD_75, data = AcousticData)
## Model 2 Assumption Check
performance::check_model(VAS_Model2)

## Model 2 Summary
summary(VAS_Model2)
Call:
lm(formula = VAS ~ Hull_bVSD_25 + Hull_bVSD_75, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-47.850 -16.576 8.382 19.448 37.237
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 42.3384 11.4211 3.707 0.000684 ***
Hull_bVSD_25 0.6376 0.8602 0.741 0.463195
Hull_bVSD_75 -0.2204 2.5674 -0.086 0.932036
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 26.66 on 37 degrees of freedom
Multiple R-squared: 0.02291, Adjusted R-squared: -0.0299
F-statistic: 0.4338 on 2 and 37 DF, p-value: 0.6513
## Model 1 and Model 2 Comparison
anova(VAS_Model1, VAS_Model2)
Analysis of Variance Table
Model 1: VAS ~ Hull_bVSD_25
Model 2: VAS ~ Hull_bVSD_25 + Hull_bVSD_75
Res.Df RSS Df Sum of Sq F Pr(>F)
1 38 26296
2 37 26291 1 5.239 0.0074 0.932
Model 3
## Specifying Model 3
VAS_Model3 <- lm(VAS ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b, data = AcousticData)
## Model 3 Assumption Check
performance::check_model(VAS_Model3)

## Model 3 Summary
summary(VAS_Model3)
Call:
lm(formula = VAS ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-56.444 -18.989 6.121 18.036 32.281
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 25.0400 16.0599 1.559 0.128
Hull_bVSD_25 -1.1164 1.4389 -0.776 0.443
Hull_bVSD_75 0.8805 2.6280 0.335 0.740
Hull_b 1.3770 0.9139 1.507 0.141
Residual standard error: 26.21 on 36 degrees of freedom
Multiple R-squared: 0.08087, Adjusted R-squared: 0.00428
F-statistic: 1.056 on 3 and 36 DF, p-value: 0.3799
## Model 2 and Model 3 Comparison
anova(VAS_Model2, VAS_Model3)
Analysis of Variance Table
Model 1: VAS ~ Hull_bVSD_25 + Hull_bVSD_75
Model 2: VAS ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b
Res.Df RSS Df Sum of Sq F Pr(>F)
1 37 26291
2 36 24731 1 1559.6 2.2702 0.1406
Model 4
## Specifying Model 4
VAS_Model4 <- lm(VAS ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b, data = AcousticData)
## Model 4 Assumption Check
performance::check_model(VAS_Model4)

## Model 4 Summary
summary(VAS_Model4)
Call:
lm(formula = VAS ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b,
data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-42.25 -14.17 5.76 16.26 41.48
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 21.0802 14.5922 1.445 0.15746
Hull_bVSD_25 -1.5708 1.3109 -1.198 0.23885
Hull_bVSD_75 1.1539 2.3798 0.485 0.63078
Hull_b 0.7682 0.8516 0.902 0.37320
VSA_b 6.6479 2.2200 2.995 0.00502 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 23.72 on 35 degrees of freedom
Multiple R-squared: 0.2683, Adjusted R-squared: 0.1847
F-statistic: 3.209 on 4 and 35 DF, p-value: 0.02405
## Model 3 and Model 4 Comparison
anova(VAS_Model3, VAS_Model4)
Analysis of Variance Table
Model 1: VAS ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b
Model 2: VAS ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b
Res.Df RSS Df Sum of Sq F Pr(>F)
1 36 24731
2 35 19687 1 5043.9 8.9671 0.00502 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Model 5
## Specifying Model 5
VAS_Model5 <- lm(VAS ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b + vowel_ED_b, data = AcousticData)
## Model 5 Assumption Check
performance::check_model(VAS_Model5)

## Model 5 Summary
summary(VAS_Model5)
Call:
lm(formula = VAS ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b +
vowel_ED_b, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-44.569 -13.697 5.187 16.183 40.204
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 12.6419 23.9197 0.529 0.6006
Hull_bVSD_25 -1.5667 1.3261 -1.181 0.2456
Hull_bVSD_75 1.3137 2.4337 0.540 0.5928
Hull_b 0.7124 0.8704 0.818 0.4188
VSA_b 5.8159 2.9132 1.996 0.0539 .
vowel_ED_b 6.5644 14.6417 0.448 0.6568
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 23.99 on 34 degrees of freedom
Multiple R-squared: 0.2726, Adjusted R-squared: 0.1657
F-statistic: 2.549 on 5 and 34 DF, p-value: 0.0461
## Model 4 and Model 5 Comparison
anova(VAS_Model4, VAS_Model5)
Analysis of Variance Table
Model 1: VAS ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b
Model 2: VAS ~ Hull_bVSD_25 + Hull_bVSD_75 + Hull_b + VSA_b + vowel_ED_b
Res.Df RSS Df Sum of Sq F Pr(>F)
1 35 19687
2 34 19572 1 115.7 0.201 0.6568
Final Model
## Specifying Final Model
VAS_Model_final <- lm(VAS ~ VSA_b, data = AcousticData)
## Final Model Assumption Check
performance::check_model(VAS_Model_final)

## Final Model Summary
summary(VAS_Model_final)
Call:
lm(formula = VAS ~ VSA_b, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-44.956 -15.943 6.754 17.153 43.062
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 24.703 8.761 2.820 0.00760 **
VSA_b 6.163 1.798 3.427 0.00148 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 23.26 on 38 degrees of freedom
Multiple R-squared: 0.2361, Adjusted R-squared: 0.216
F-statistic: 11.74 on 1 and 38 DF, p-value: 0.001482
confint(VAS_Model_final)
2.5 % 97.5 %
(Intercept) 6.966936 42.438084
VSA_b 2.521887 9.803467
Research Q2: Relationship between OT and VAS
Model 1
# Specify Model
OT_VAS_model <- lm(transAcc ~ VAS*Etiology + VAS*Sex, data = AcousticData)
# Assumption Check
performance::check_model(OT_VAS_model)

# Model Results
summary(OT_VAS_model)
Call:
lm(formula = transAcc ~ VAS * Etiology + VAS * Sex, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-14.910 -4.525 -1.280 5.529 16.932
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 10.8993562 5.7092981 1.909 0.0659 .
VAS 0.8924319 0.1276625 6.991 9.1e-08 ***
EtiologyAtaxic 2.9854239 9.5149402 0.314 0.7559
EtiologyHD 2.1009983 7.3948950 0.284 0.7783
EtiologyPD -2.4903757 10.1590855 -0.245 0.8080
SexM 6.8939642 7.0796700 0.974 0.3380
VAS:EtiologyAtaxic -0.0019088 0.1791048 -0.011 0.9916
VAS:EtiologyHD 0.0007804 0.1453318 0.005 0.9958
VAS:EtiologyPD 0.0320470 0.1732105 0.185 0.8545
VAS:SexM -0.1220661 0.1241230 -0.983 0.3333
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 8.488 on 30 degrees of freedom
Multiple R-squared: 0.9031, Adjusted R-squared: 0.874
F-statistic: 31.06 on 9 and 30 DF, p-value: 8.181e-13
Final Model
# Specify Final Model
OT_VAS_final <- lm(transAcc ~ VAS, data = AcousticData)
confint(OT_VAS_final)
2.5 % 97.5 %
(Intercept) 8.1038688 19.3870846
VAS 0.7637645 0.9580856
# Model Results
summary(OT_VAS_final)
Call:
lm(formula = transAcc ~ VAS, data = AcousticData)
Residuals:
Min 1Q Median 3Q Max
-13.6882 -4.9316 -0.4408 4.9974 17.2110
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 13.74548 2.78681 4.932 1.64e-05 ***
VAS 0.86093 0.04799 17.938 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 7.873 on 38 degrees of freedom
Multiple R-squared: 0.8944, Adjusted R-squared: 0.8916
F-statistic: 321.8 on 1 and 38 DF, p-value: < 2.2e-16
Manuscript Tables
##Descriptives Table
gtData <- AcousticData %>%
rbind(.,AcousticData %>%
dplyr::mutate(Etiology = "All Etiologies")) %>%
rbind(.,AcousticData %>%
rbind(.,AcousticData %>%
dplyr::mutate(Etiology = "All Etiologies")) %>%
dplyr::mutate(Sex = "All")) %>%
dplyr::mutate(Sex = as.factor(Sex),
Etiology = as.factor(Etiology)) %>%
dplyr::group_by(Sex, Etiology) %>%
dplyr::summarize(VSA_mean = mean(VSA_b, na.rm =T), VSA_sd = sd(VSA_b, na.rm = T),
Disp_mean = mean(vowel_ED_b, na.rm =T), Disp_sd = sd(vowel_ED_b, na.rm =T),
Hull_mean = mean(Hull_b, na.rm =T), Hull_sd = sd(Hull_b, na.rm =T),
VSD25_mean = mean(Hull_bVSD_25, na.rm =T), VSD25_sd = sd(Hull_bVSD_25, na.rm =T),
VSD50_mean = mean(Hull_bVSD_50, na.rm =T), VSD50_sd = sd(Hull_bVSD_50, na.rm =T),
VSD75_mean = mean(Hull_bVSD_75, na.rm =T), VSD75_sd = sd(Hull_bVSD_75, na.rm =T),
VAS_mean = mean(VAS, na.rm =T), VAS_sd = sd(VAS, na.rm =T),
OT_mean = mean(transAcc, na.rm =T), OT_sd = sd(transAcc, na.rm =T)) %>%
pivot_longer(cols = VSA_mean:OT_sd, names_to = "Measure",
values_to = "Value") %>%
dplyr::mutate(meanSD = ifelse(grepl("_mean",Measure),"M","sd"),
Measure = gsub("_mean","",Measure),
Measure = gsub("_sd","",Measure),
Etiology = paste(Etiology,meanSD, sep = "_"),
Sex = case_when(
Sex == "All" ~ "All Speakers",
Sex == "M" ~ "Male",
Sex == "F" ~ "Female"
)) %>%
dplyr::select(!meanSD) %>%
pivot_wider(names_from = Etiology, values_from = "Value") %>%
dplyr::filter(Measure != "VSD50")
`summarise()` has grouped output by 'Sex'. You can override using the `.groups` argument.
gtData %>%
gt::gt(
rowname_col = "Measure",
groupname_col = "Sex",
) %>%
fmt_number(
columns = 'All Etiologies_M':PD_sd,
decimals = 2
) %>%
tab_spanner(
label = "All Etiologies",
columns = c('All Etiologies_M', 'All Etiologies_sd')
) %>%
tab_spanner(
label = "ALS",
columns = c(ALS_M, ALS_sd)
) %>%
tab_spanner(
label = "PD",
columns = c(PD_M, PD_sd)
) %>%
tab_spanner(
label = "HD",
columns = c(HD_M, HD_sd)
) %>%
tab_spanner(
label = "Ataxic",
columns = c(Ataxic_M, Ataxic_sd)
) %>%
cols_label(
'All Etiologies_M' = "M",
'All Etiologies_sd' = "SD",
ALS_M = "M",
ALS_sd = "SD",
PD_M = "M",
PD_sd = "SD",
HD_M = "M",
HD_sd = "SD",
Ataxic_M = "M",
Ataxic_sd = "SD"
) %>%
gtsave("DescriptivesTable.html", path = "Tables")
OT Model
sjPlot::tab_model(OT_Model1,OT_Model2,OT_Model3, OT_Model4, OT_Model5, OT_Model_final,
show.ci = F,
p.style = "stars",
file = "Tables/OT Models.html")
VAS Model
sjPlot::tab_model(VAS_Model1,VAS_Model2,VAS_Model3, VAS_Model4, VAS_Model5, VAS_Model_final,
show.ci = F,
p.style = "stars",
file = "Tables/VAS Models.html")
OT vs. VAS
sjPlot::tab_model(OT_VAS_model,OT_VAS_final,
show.ci = F,
show.reflvl = TRUE,
p.style = "stars",
file = "Tables/OT and VAS Comparison.html")
Manuscript Figures
Example Measures

Filtering Process
formantAlpha <- .20
myPal <- c("#1279B5","#2D2D37")
Pitch_PRAAT <- list.files(path = paste("Prepped Data/Example Data/", sep = ""),
pattern = ".Pitch", ignore.case = T) %>%
paste("Prepped Data/Example Data/",., sep = "") %>%
read.delim(., header = F) %>%
dplyr::rename(Pitch = V1) %>%
dplyr::mutate(Pitch = gsub("--undefined--",NA,Pitch),
Pitch = as.numeric(Pitch))
Formants_PRAAT <- list.files(path = paste("Prepped Data/Example Data/", sep = ""),
pattern = "_Formant", ignore.case = T) %>%
paste("Prepped Data/Example Data/",., sep = "") %>%
read.delim(., header = T) %>%
dplyr::select(!c(nformants, B1.Hz., B2.Hz., B3.Hz., F4.Hz., B4.Hz., F5.Hz., B5.Hz.)) %>%
dplyr::rename(Time_s = time.s.,
F1_Hz = F1.Hz.,
F2_Hz = F2.Hz.,
F3_Hz = F3.Hz.) %>%
dplyr::mutate(F1_Hz = ifelse(F1_Hz == 0, NA, F1_Hz),
F2_Hz = ifelse(F2_Hz == 0, NA, F2_Hz),
F3_Hz = ifelse(F3_Hz == 0, NA, F3_Hz)) %>%
dplyr::mutate(F1_Hz = as.numeric(F1_Hz),
F2_Hz = as.numeric(F2_Hz),
F3_Hz = suppressWarnings(as.numeric(F3_Hz)),
Time_ms = Time_s / 1000,
F1_kHz = F1_Hz / 1000,
F2_kHz = F2_Hz / 1000,
F3_kHz = F3_Hz / 1000,
F1_b = emuR::bark(F1_Hz),
F2_b = emuR::bark(F2_Hz),
F3_b = emuR::bark(F3_Hz)) %>%
dplyr::select(!Time_s) %>%
dplyr::relocate(Time_ms, .before = F1_Hz) %>%
cbind(.,Pitch_PRAAT)
c <- 2
while(c < NROW(Formants_PRAAT)){
Formants_PRAAT$F1_Hz[c] <- ifelse(is.na(Formants_PRAAT$F1_Hz[c-1]) &&
is.na(Formants_PRAAT$F1_Hz[c+1]),
NA,
Formants_PRAAT$F1_Hz[c])
Formants_PRAAT$F2_Hz[c] <- ifelse(is.na(Formants_PRAAT$F2_Hz[c-1]) &&
is.na(Formants_PRAAT$F2_Hz[c+1]),
NA,
Formants_PRAAT$F2_Hz[c])
c <- c + 1
}
rm(c)
# Raw Formants ----
f1 <- ggplot(aes(x=F2_b,
y=F1_b),
data = Formants_PRAAT) +
geom_point(shape = 21, color = myPal[2]) +
scale_y_reverse() +
scale_x_reverse() +
scale_color_manual(values = myPal) +
theme_classic() + labs(title = paste("Raw Formant Values")) + xlab("F2 (bark)") + ylab("F1 (bark)") +
theme(plot.title = element_text(hjust = 0.5),
aspect.ratio = 1,
legend.title = element_blank(),
legend.text = element_text(size=12))
# Step #1: Voiced Segments ----
plotData <- Formants_PRAAT %>%
dplyr::mutate(isOutlier = case_when(
is.na(Pitch) ~ "Removed",
TRUE ~ "Retained"
))
f2 <- ggplot(data = plotData,
aes(x = F2_b,
y = F1_b,
color = isOutlier)) +
geom_point(shape = 21, data = plotData %>%
dplyr::filter(isOutlier == "Removed")) +
geom_point(shape = 21, data = plotData %>%
dplyr::filter(isOutlier == "Retained")) +
scale_y_reverse() +
scale_x_reverse() +
scale_color_manual(values = myPal) +
theme_classic() + labs(title = paste("Step #1:\nVoiced Segments")) +
xlab("F2 (bark)") +
ylab("F1 (bark)") +
theme(plot.title = element_text(hjust = 0.5),
aspect.ratio = 1,
legend.title = element_blank(),
legend.text = element_text(size=12))
# Step 2: MAD ----
plotData <- Formants_PRAAT %>%
dplyr::filter(!is.na(Pitch)) %>%
dplyr::mutate(F1_mad = (abs(F1_Hz - median(F1_Hz))/ mad(F1_Hz, constant = 1.4826)) > 2.5,
F2_mad = (abs(F2_Hz - median(F2_Hz))/ mad(F2_Hz, constant = 1.4826)) > 2.5,
isOutlier = case_when(
F1_mad == TRUE | F2_mad == TRUE ~ "Removed",
TRUE ~ "Retained"
))
f3 <- ggplot(data = plotData,
aes(x = F2_b,
y = F1_b,
color = isOutlier)) +
geom_point(shape = 21, data = plotData %>%
dplyr::filter(isOutlier == "Removed")) +
geom_point(shape = 21, data = plotData %>%
dplyr::filter(isOutlier == "Retained")) +
scale_y_reverse() +
scale_x_reverse() +
scale_color_manual(values = myPal) +
theme_classic() +
labs(title = paste("Step #2:\nMedian Absolute Deviation")) +
xlab("F2 (bark)") +
ylab("F1 (bark)") +
theme(plot.title = element_text(hjust = 0.5),
aspect.ratio = 1,
legend.title = element_blank(),
legend.text = element_text(size=12))
# Step 3: Mahalanhobis Distance ----
plotData <- Formants_PRAAT %>%
dplyr::filter(!is.na(Pitch)) %>%
dplyr::mutate(F1_mad = (abs(F1_Hz - median(F1_Hz))/ mad(F1_Hz, constant = 1.4826)) > 2.5,
F2_mad = (abs(F2_Hz - median(F2_Hz))/ mad(F2_Hz, constant = 1.4826)) > 2.5) %>%
dplyr::filter(F1_mad == FALSE & F2_mad == FALSE) %>%
dplyr::mutate(mDist = mahalanobis(cbind(.$F1_Hz, .$F2_Hz),
colMeans(cbind(.$F1_Hz, .$F2_Hz)),
cov = cov(cbind(.$F1_Hz, .$F2_Hz))),
mDist_sd = abs(scale(mDist,center = T)),
isOutlier = case_when(
mDist_sd < 2 ~ "Retained",
TRUE ~ "Removed"
))
f4 <- ggplot(data = plotData,
aes(x = F2_b,
y = F1_b,
color = isOutlier)) +
geom_point(shape = 21, data = plotData %>%
dplyr::filter(isOutlier == "Removed")) +
geom_point(shape = 21, data = plotData %>%
dplyr::filter(isOutlier == "Retained")) +
scale_y_reverse() +
scale_x_reverse() +
scale_color_manual(values = myPal) +
theme_classic() + labs(title = paste("Step #3:\nMahalanobis Distance")) + xlab("F2 (bark)") + ylab("F1 (bark)") +
theme(plot.title = element_text(hjust = 0.5),
aspect.ratio = 1,
legend.title = element_blank(),
legend.text = element_text(size=12))
# Final Formants ----
plotData <- Formants_PRAAT %>%
dplyr::filter(!is.na(Pitch)) %>%
dplyr::mutate(F1_mad = (abs(F1_Hz - median(F1_Hz))/ mad(F1_Hz, constant = 1.4826)) > 2.5,
F2_mad = (abs(F2_Hz - median(F2_Hz))/ mad(F2_Hz, constant = 1.4826)) > 2.5) %>%
dplyr::filter(F1_mad == FALSE & F2_mad == FALSE) %>%
dplyr::mutate(mDist = mahalanobis(cbind(.$F1_Hz, .$F2_Hz),
colMeans(cbind(.$F1_Hz, .$F2_Hz)),
cov = cov(cbind(.$F1_Hz, .$F2_Hz))),
mDist_sd = abs(scale(mDist,center = T))) %>%
dplyr::filter(mDist_sd < 2)
f5 <- ggplot(aes(x=F2_b,
y=F1_b),
data = plotData,
inherit.aes = FALSE) +
geom_point(shape = 21, color = myPal[2]) +
scale_y_reverse() +
scale_x_reverse() +
theme_classic() + labs(title = paste("Final Formant Values")) + xlab("F2 (bark)") + ylab("F1 (bark)") +
theme(plot.title = element_text(hjust = 0.5),
aspect.ratio = 1, legend.title = element_blank())
# Comibing plots
filteredPlot <- f1 + f2 + f3 + f4 + f5 + patchwork::guide_area() +
patchwork::plot_layout(guides = 'collect',
ncol = 3)
filteredPlot
ggsave(plot = filteredPlot, "Plots/Filtered Formants.png",
height = 6,
width = 8,
units = "in",
scale = .9)
OT vs. VAS
plotData_Int <- AcousticData %>%
dplyr::filter(!grepl("_rel", Speaker)) %>%
dplyr::group_by(Speaker) %>%
dplyr::mutate(segMin = base::min(VAS, transAcc),
segMax = base::max(VAS, transAcc),
ratingAvg = mean(VAS, transAcc, na.rm = T),
Speaker = as.factor(Speaker),
Etiology = as.factor(Etiology)) %>%
arrange(segMax)
my_pal <- c("#f26430", "#272D2D","#256eff")
# With a bit more style
plot_Int <- ggplot(plotData_Int) +
geom_segment(aes(x = fct_inorder(Speaker),
xend = Speaker,
y = segMin,
yend = segMax,
color = Etiology)) +
geom_point(aes(x = Speaker,
y = VAS,
color = Etiology),
#color = my_pal[1],
size = 3,
shape = 19) +
geom_point(aes(x = Speaker,
y = transAcc,
color = Etiology),
#color = my_pal[2],
size = 3,
shape = 15) +
coord_flip()+
theme_classic() +
theme(
legend.position = "none",
panel.border = element_blank(),
) +
xlab("") +
ylab("Speech Intelligibility") +
ggtitle("Speech Intelligibility") +
ylim(c(0,100))
plot_Int
myPal <- c("#1AAD77", "#1279B5", "#FFBF00", "#FD7853", "#BF3178")
myShapes <- c(16, 18, 17, 15)
scatter1 <- ggplot(plotData_Int,
aes(x = VAS,
y = transAcc,
color = Etiology,
shape = Etiology,
linetype = Etiology)) +
geom_point() +
#geom_smooth(method = "lm", se = F) +
geom_abline(intercept = 0, slope = 1) +
coord_cartesian(xlim = c(0,100), ylim = c(0,100)) +
labs(x = "Intelligibility (VAS)", y = "Intelligibility (OT)") +
scale_color_manual(values = myPal) +
scale_shape_manual(values = myShapes) +
theme_classic() +
theme(aspect.ratio=1,
legend.position="right")
scatter2 <- ggplot(plotData_Int,
aes(x = VAS,
y = transAcc,
color = Etiology,
shape = Etiology,
linetype = Etiology)) +
#geom_point() +
geom_smooth(method = "lm", se = F) +
geom_abline(intercept = 0, slope = 1) +
coord_cartesian(xlim = c(0,100), ylim = c(0,100)) +
labs(x = "Intelligibility (VAS)", y = "Intelligibility (OT)") +
scale_color_manual(values = myPal) +
scale_shape_manual(values = myShapes) +
theme_classic() +
theme(aspect.ratio=1,
legend.position="right")
combinedScatter <- ggarrange(scatter1,
scatter2,
common.legend = F,
ncol = 2,
nrow = 1)
combinedScatter
ggsave(filename = "Plots/OT and VAS Scatterplot.png",
plot = combinedScatter,
height = 2,
width = 6,
units = "in",
scale = 1)
rm(scatter1, scatter2, combinedScatter)
Model Scatterplot
modelFigureData <- AcousticData %>%
dplyr::filter(!grepl("_rel",Speaker)) %>%
dplyr::select(Speaker, Etiology, Sex, VSA_b, vowel_ED_b, Hull_b, Hull_bVSD_25, Hull_bVSD_75, VAS, transAcc) %>%
dplyr::mutate(Speaker = as.factor(Speaker),
Etiology = as.factor(Etiology),
Sex = as.factor(Sex)) %>%
tidyr::pivot_longer(cols = VAS:transAcc, names_to = "IntType", values_to = "Int") %>%
dplyr::mutate(IntType = case_when(
IntType == "transAcc" ~ "OT",
TRUE ~ "VAS"
),
IntType = as.factor(IntType))
ylabel <- "Intelligibility"
myPal <- c("#2D2D37", "#1279B5")
myPalShape <- c(19, 1)
VSA <- modelFigureData %>%
ggplot() +
aes(x = VSA_b,
y = Int,
color = IntType,
shape = IntType,
linetype = IntType) +
geom_point() +
geom_smooth(method = "lm", se = T, fill = "light grey") +
xlab(expression("VSA (Bark"^2*")")) +
ylab(ylabel) +
coord_cartesian(ylim = c(0,100)) +
theme_classic() +
theme(plot.title = element_text(hjust = 0.5, face = "bold"),
aspect.ratio=1) +
scale_color_manual(values = myPal) +
scale_shape_manual(values = myPalShape) +
labs(color="Intelligibility Type",
shape = "Intelligibility Type",
linetype = "Intelligibility Type")
disp <- modelFigureData %>%
ggplot() +
aes(x = vowel_ED_b,
y = Int,
color = IntType,
shape = IntType,
linetype = IntType) +
geom_point() +
geom_smooth(method = "lm", se = T, fill = "light grey") +
xlab("Corner Dispersion (Bark)") +
ylab(ylabel) +
coord_cartesian(ylim = c(0,100)) +
theme_classic() +
theme(aspect.ratio=1) +
scale_color_manual(values = myPal) +
scale_shape_manual(values = myPalShape) +
labs(color="Intelligibility Type",
shape = "Intelligibility Type",
linetype = "Intelligibility Type")
Hull <- modelFigureData %>%
ggplot() +
aes(x = Hull_b,
y = Int,
color = IntType,
shape = IntType,
linetype = IntType) +
geom_point() +
geom_smooth(method = "lm", se = T, fill = "light grey") +
xlab(expression("VSA"[Hull]*" (Bark"^2*")")) +
ylab(ylabel) +
coord_cartesian(ylim = c(0,100)) +
theme_classic() +
theme(aspect.ratio=1) + theme(legend.position = "none") +
scale_color_manual(values = myPal) +
scale_shape_manual(values = myPalShape) +
labs(color="Intelligibility Type",
shape = "Intelligibility Type",
linetype = "Intelligibility Type")
vsd25 <- modelFigureData %>%
ggplot() +
aes(x = Hull_bVSD_25,
y = Int,
color = IntType,
shape = IntType,
linetype = IntType) +
geom_point() +
geom_smooth(method = "lm", se = T, fill = "light grey") +
xlab(expression("VSD"[25]*" (Bark"^2*")")) +
ylab(ylabel) +
coord_cartesian(ylim = c(0,100)) +
theme_classic() +
theme(aspect.ratio=1) + theme(legend.position = "none") +
scale_color_manual(values = myPal) +
scale_shape_manual(values = myPalShape) +
labs(color="Intelligibility Type",
shape = "Intelligibility Type",
linetype = "Intelligibility Type")
vsd75 <- modelFigureData %>%
ggplot() +
aes(x = Hull_bVSD_75,
y = Int,
color = IntType,
shape = IntType,
linetype = IntType) +
geom_point() +
geom_smooth(method = "lm", se = T, fill = "light grey") +
xlab(expression("VSD"[75]*" (Bark"^2*")")) +
ylab(ylabel) +
coord_cartesian(ylim = c(0,100)) +
theme_classic() +
theme(aspect.ratio=1) + theme(legend.position = "none") +
scale_color_manual(values = myPal) +
scale_shape_manual(values = myPalShape) +
labs(color="Intelligibility Type",
shape = "Intelligibility Type",
linetype = "Intelligibility Type")
# Creating OT Scatterplot Figure
scatter <- VSA + disp + patchwork::guide_area() + Hull + vsd25 + vsd75 +
patchwork::plot_layout(guides = 'collect',
ncol = 3)
scatter
ggsave("Plots/ModelFigure.png", scatter,
height = 4,
width = 6,
units = "in",
scale = 1.1)
Speaker Demographics
SpeakerDemo <- AcousticData %>%
dplyr::select(c(Speaker, Sex, Etiology))
Ages <- rio::import("Prepped Data/Speaker Ages.xlsx")
SpeakerDemo <- full_join(SpeakerDemo, Ages, by = "Speaker")
SpeakerDemoInfo <- SpeakerDemo %>%
furniture::table1(Sex, Etiology, Age, na.rm = F)
SpeakerDemoInfo
SpeakerDemo %>%
dplyr::summarize(mean_age = mean(Age, na.rm = T), age_sd = sd(Age, na.rm = T), age_range = range(Age, na.rm = T))
LS0tCnRpdGxlOiAiVm93ZWwgQWNvdXN0aWNzIGFzIFByZWRpY3RvcnMgb2YgU3BlZWNoIEludGVsbGlnaWJpbGl0eSBpbiBEeXNhcnRocmlhIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpUaGlzIGlzIHRoZSBjb2RlIGZvciB0aGUgc3RhdGlzdGljYWwgYW5hbHlzaXMgZm9yICJWb3dlbCBBY291c3RpY3MgYXMgUHJlZGljdG9ycyBvZiBTcGVlY2ggSW50ZWxsaWdpYmlsaXR5IGluIER5c2FydGhyaWEuIgoKIyBMb2FkaW5nIFBhY2thZ2VzCgpgYGB7cn0KCmxpYnJhcnkocmlvKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShpcnIpICMgaW5zdGFsbC5wYWNrYWdlcygnaXJyJykKbGlicmFyeShwZXJmb3JtYW5jZSkKbGlicmFyeShjYXIpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KCJIbWlzYyIpICMgaW5zdGFsbC5wYWNrYWdlcygnSG1pc2MnKQpsaWJyYXJ5KGdncmlkZ2VzKQpsaWJyYXJ5KGZ1cm5pdHVyZSkgIyBpbnN0YWxsLnBhY2thZ2VzKCdmdXJuaXR1cmUnKQpsaWJyYXJ5KGd0KQpsaWJyYXJ5KHBhdGNod29yaykKbGlicmFyeShrcykKbGlicmFyeShlbXVSKSAjIGluc3RhbGwucGFja2FnZXMoJ2VtdVInKQpsaWJyYXJ5KGdlb210ZXh0cGF0aCkgIyByZW1vdGVzOjppbnN0YWxsX2dpdGh1YigiQWxsYW5DYW1lcm9uL2dlb210ZXh0cGF0aCIpCgpgYGAKCiMgVXBsb2FkIERhdGFzZXRzCgpgYGB7cn0KClJlbGlhYmlsaXR5IDwtIHJpbzo6aW1wb3J0KCJQcmVwcGVkIERhdGEvUmVsaWFiaWxpdHkgRGF0YS5jc3YiKQpBY291c3RpY0RhdGEgPC0gcmlvOjppbXBvcnQoIlByZXBwZWQgRGF0YS9BY291c3RpY01lYXN1cmVzLmNzdiIpICU+JQogIGRwbHlyOjptdXRhdGUoaW50RGlmZiA9IFZBUyAtIHRyYW5zQWNjKQoKQWNvdXN0aWNEYXRhIDwtIEFjb3VzdGljRGF0YSAlPiUKICBkcGx5cjo6ZmlsdGVyKCFncmVwbCgiX3JlbCIsIFNwZWFrZXIpKSAlPiUKICBkcGx5cjo6c2VsZWN0KGMoU3BlYWtlciwgU2V4LCBFdGlvbG9neSwgdm93ZWxfRURfYiwgVlNBX2IsIEh1bGxfYiwgSHVsbF9iVlNEXzI1LCBIdWxsX2JWU0RfNTAsIEh1bGxfYlZTRF83NSwgVkFTLCB0cmFuc0FjYykpICU+JQogIGRwbHlyOjptdXRhdGUoRXRpb2xvZ3kgPSBhcy5mYWN0b3IoRXRpb2xvZ3kpLAogICAgICAgICAgICAgICAgU2V4ID0gYXMuZmFjdG9yKFNleCksCiAgICAgICAgICAgICAgICBTcGVha2VyID0gYXMuZmFjdG9yKFNwZWFrZXIpKQoKTGlzdGVuZXJzIDwtIHJpbzo6aW1wb3J0KCJQcmVwcGVkIERhdGEvTGlzdGVuZXJfRGVtb2dyYXBoaWNzLmNzdiIpICU+JQogIGRwbHlyOjpzZWxlY3QoIWMoU3RhcnREYXRlOnByb2xvZmljSUQsIFEyLjRfNl9URVhULCBRMy4yXzhfVEVYVCwgQXVkaW9DaGVjazpFUDMpKQoKTGlzdGVuZXJzJHJhY2VbTGlzdGVuZXJzJFEzLjNfN19URVhUID09ICJOYXRpdmUgQW1lcmljYW4vIEFmcmljYW4gYW1lcmNpbmciXSA8LSAiQmlyYWNpYWwgb3IgTXVsdGlyYWNpYWwiCmBgYAoKCiMgSW50ZXItcmF0ZXIgUmVsaWFiaWxpdHkKClR3byByYXRlcnMgKHRoZSBmaXJzdCB0d28gYXV0aG9ycykgY29tcGxldGVkIHZvd2VsIHNlZ21lbnRhdGlvbiBmb3IgdGhlIHNwZWFrZXJzLiBUbyBjYWxjdWxhdGUgaW50ZXItcmF0ZXIgcmVsaWFiaWxpdHksIDIwJSBvZiB0aGUgc3BlYWtlcnMgd2VyZSBzZWdtZW50ZWQgYWdhaW4gYnkgdGhlIG90aGVyIHJhdGVyLiBUd28td2F5IGludHJhY2xhc3MgY29lZmZpY2llbnRzIHdlcmUgY29tcHV0ZWQgZm9yIHRoZSBleHRyYWN0ZWQgRjEgYW5kIEYyIGZyb20gdGhlIHRlbXBvcmFsIG1pZHBvaW50IG9mIHRoZSB2b3dlbCBzZWdtZW50cy4gU2luY2Ugb25seSBvbmUgc2V0IG9mIHJhdGluZ3Mgd2lsbCBiZSB1c2VkIGluIHRoZSBkYXRhIGFuYWx5c2lzLCB3ZSBmb2N1cyBvbiB0aGUgc2luZ2xlIElDQyByZXN1bHRzIGFuZCBpbnRlcnByZXRhdGlvbi4gSG93ZXZlciwgd2UgYWxzbyByZXBvcnQgdGhlIGF2ZXJhZ2UgSUNDIHZhbHVlcyB0byBiZSBjb21wcmVoZW5zaXZlLgoKYGBge3J9CgojIyBDcmVhdGluZyBuZXcgZGF0YSBmcmFtZXMgdG8gY2FsY3VsYXRlIElDQyBmb3IgZXh0cmFjdGVkIEYxIGFuZCBGMiB2YWx1ZXMKCkYxX1JlbCA8LSBSZWxpYWJpbGl0eSAlPiUKICBkcGx5cjo6c2VsZWN0KGMoRjEsIEYxX3JlbCkpCgpGMl9SZWwgPC0gUmVsaWFiaWxpdHkgJT4lCiAgZHBseXI6OnNlbGVjdChjKEYyLCBGMl9yZWwpKQogIAojIyBTaW5nbGUgSUNDIGZvciBGMQpTaW5nbGVfRjEgPC0gaXJyOjppY2MoRjFfUmVsLCBtb2RlbCA9ICJ0d293YXkiLCB0eXBlID0gImFncmVlbWVudCIsIHVuaXQgPSAic2luZ2xlIikKCiMjIEF2ZXJhZ2UgSUNDIGZvciBGMQpBdmVyYWdlX0YxIDwtIGlycjo6aWNjKEYxX1JlbCwgbW9kZWwgPSAidHdvd2F5IiwgdHlwZSA9ICJhZ3JlZW1lbnQiLCB1bml0ID0gImF2ZXJhZ2UiKQoKIyMgU2luZ2xlIElDQyBmb3IgRjIKU2luZ2xlX0YyIDwtIGlycjo6aWNjKEYyX1JlbCwgbW9kZWwgPSAidHdvd2F5IiwgdHlwZSA9ICJhZ3JlZW1lbnQiLCB1bml0ID0gInNpbmdsZSIpCgojIyBBdmVyYWdlIElDQyBmb3IgRjIKQXZlcmFnZV9GMiA8LSBpcnI6OmljYyhGMl9SZWwsIG1vZGVsID0gInR3b3dheSIsIHR5cGUgPSAiYWdyZWVtZW50IiwgdW5pdCA9ICJhdmVyYWdlIikKCiMjIEludGVyLXJhdGVyIHJlbGlhYmlsaXR5IHJlc3VsdHMgYW5kIGludGVycHJldGF0aW9uCgpwcmludChwYXN0ZSgiU2luZ2xlIElDQyBmb3IgRjEgaXMgIiwgcm91bmQoU2luZ2xlX0YxJHZhbHVlLCBkaWdpdHMgPSAzKSwgIi4gIiwgCiAgICAgICAgICAgICJUaGUgOTUlIENJIGlzIFsiLCByb3VuZChTaW5nbGVfRjEkbGJvdW5kLCBkaWdpdHMgPSAzKSwgIiAtICIsIHJvdW5kKFNpbmdsZV9GMSR1Ym91bmQsIGRpZ2l0cyA9IDMpLCAiXS4iLCBzZXAgPSAiIikpCgpwcmludChwYXN0ZSgiU2luZ2xlIElDQyBmb3IgRjIgaXMgIiwgcm91bmQoU2luZ2xlX0YyJHZhbHVlLCBkaWdpdHMgPSAzKSwgIi4gIiwgCiAgICAgICAgICAgICJUaGUgOTUlIENJIGlzIFsiLCByb3VuZChTaW5nbGVfRjIkbGJvdW5kLCBkaWdpdHMgPSAzKSwgIiAtICIsIHJvdW5kKFNpbmdsZV9GMiR1Ym91bmQsIGRpZ2l0cyA9IDMpLCAiXS4iLCBzZXAgPSAiIikpCgpwcmludChwYXN0ZSgiQXZlcmFnZSBJQ0MgZm9yIEYxIGlzICIsIHJvdW5kKEF2ZXJhZ2VfRjEkdmFsdWUsIGRpZ2l0cyA9IDMpLCAiLiAiLCAKICAgICAgICAgICAgIlRoZSA5NSUgQ0kgaXMgWyIsIHJvdW5kKEF2ZXJhZ2VfRjEkbGJvdW5kLCBkaWdpdHMgPSAzKSwgIiAtICIsIHJvdW5kKEF2ZXJhZ2VfRjEkdWJvdW5kLCBkaWdpdHMgPSAzKSwgIl0uIiwgc2VwID0gIiIpKQoKcHJpbnQocGFzdGUoIkF2ZXJhZ2UgSUNDIGZvciBGMiBpcyAiLCByb3VuZChBdmVyYWdlX0YyJHZhbHVlLCBkaWdpdHMgPSAzKSwgIi4gIiwgCiAgICAgICAgICAgICJUaGUgOTUlIENJIGlzIFsiLCByb3VuZChBdmVyYWdlX0YyJGxib3VuZCwgZGlnaXRzID0gMyksICIgLSAiLCByb3VuZChBdmVyYWdlX0YyJHVib3VuZCwgZGlnaXRzID0gMyksICJdLiIsIHNlcCA9ICIiKSkKCnByaW50KCJUaHVzLCBpbnRlcnJhdGVyIHJlbGlhYmlsaXR5IGZvciB0aGUgZXh0cmFjdGVkIEYxIGFuZCBGMiB2YWx1ZXMgZnJvbSB0aGUgdm93ZWwgc2VnbWVudHMgd2FzIGdvb2QgdG8gZXhjZWxsZW50LiIpCgojIyBSZW1vdmluZyBleHRyYSBkYXRhIGZyYW1lcyBmcm9tIGVudmlyb25tZW50CgpybShGMV9SZWwsIEYyX1JlbCwgUmVsaWFiaWxpdHksIFNpbmdsZV9GMSwgU2luZ2xlX0YyLCBBdmVyYWdlX0YxLCBBdmVyYWdlX0YyKQoKYGBgCgoKIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzCgojIyBDb3JyZWxhdGlvbnMKCmBgYHtyfQpDb3JyTWF0cml4IDwtIEFjb3VzdGljRGF0YSAlPiUKICBkcGx5cjo6c2VsZWN0KFZTQV9iLCB2b3dlbF9FRF9iLCBIdWxsX2IsIEh1bGxfYlZTRF8yNSwgSHVsbF9iVlNEXzUwLCBIdWxsX2JWU0RfNzUsIFZBUywgdHJhbnNBY2MpICU+JQogIGFzLm1hdHJpeCgpICU+JQogIEhtaXNjOjpyY29ycigpCgpDb3JyTWF0cml4IDwtIENvcnJNYXRyaXgkcgoKc3RhdHM6OmNvci50ZXN0KEFjb3VzdGljRGF0YSRWU0FfYiwgQWNvdXN0aWNEYXRhJHZvd2VsX0VEX2IsIG1ldGhvZCA9ICJwZWFyc29uIikKc3RhdHM6OmNvci50ZXN0KEFjb3VzdGljRGF0YSRIdWxsX2IsIEFjb3VzdGljRGF0YSRIdWxsX2JWU0RfMjUsIG1ldGhvZCA9ICJwZWFyc29uIikKCndyaXRlLmNzdihDb3JyTWF0cml4LCBmaWxlID0gIlRhYmxlcy9Db3JyZWxhdGlvbiBNYXRyaXguY3N2IikKcm0oQ29yck1hdHJpeCkKCmBgYAoKIyBSZXNlYXJjaCBRMTogTW9kZWxpbmcgSW50ZWxsaWdpYmlsaXR5CgojIyBPcnRob2dyYXBoaWMgVHJhbnNjcmlwdGlvbnMKTW9kZWwgMQpgYGB7cn0KCiMgU3BlY2lmeWluZyBNb2RlbCAxCgpPVF9Nb2RlbDEgPC0gbG0odHJhbnNBY2MgfiBIdWxsX2JWU0RfMjUsIGRhdGEgPSBBY291c3RpY0RhdGEpCgojIyBNb2RlbCAxIEFzc3VtcHRpb25zIAoKcGVyZm9ybWFuY2U6OmNoZWNrX21vZGVsKE9UX01vZGVsMSkKCiMjIE1vZGVsIDEgU3VtbWFyeQoKc3VtbWFyeShPVF9Nb2RlbDEpCgpgYGAKCk1vZGVsIDIKYGBge3J9CgojIyBTcGVjaWZ5aW5nIE1vZGVsIDIKCk9UX01vZGVsMiA8LSBsbSh0cmFuc0FjYyB+IEh1bGxfYlZTRF8yNSArIEh1bGxfYlZTRF83NSwgZGF0YSA9IEFjb3VzdGljRGF0YSkKCiMjIE1vZGVsIDIgQXNzdW1wdGlvbiBDaGVjawoKcGVyZm9ybWFuY2U6OmNoZWNrX21vZGVsKE9UX01vZGVsMikKCiMjIE1vZGVsIDIgU3VtbWFyeQoKc3VtbWFyeShPVF9Nb2RlbDIpCgojIyBNb2RlbCAxIGFuZCBNb2RlbCAyIENvbXBhcmlzb24KCmFub3ZhKE9UX01vZGVsMSwgT1RfTW9kZWwyKQoKYGBgCgpNb2RlbCAzCmBgYHtyfQoKIyMgU3BlY2lmeWluZyBNb2RlbCAzCgpPVF9Nb2RlbDMgPC0gbG0odHJhbnNBY2MgfiBIdWxsX2JWU0RfMjUgKyBIdWxsX2JWU0RfNzUgKyBIdWxsX2IsIGRhdGEgPSBBY291c3RpY0RhdGEpCgojIyBNb2RlbCAzIEFzc3VtcHRpb24gQ2hlY2sKCnBlcmZvcm1hbmNlOjpjaGVja19tb2RlbChPVF9Nb2RlbDMpCgojIyBNb2RlbCAzIFN1bW1hcnkKCnN1bW1hcnkoT1RfTW9kZWwzKQoKIyMgTW9kZWwgMiBhbmQgTW9kZWwgMyBDb21wYXJpc29uCgphbm92YShPVF9Nb2RlbDIsIE9UX01vZGVsMykKCmBgYAoKTW9kZWwgNApgYGB7cn0KCiMjIFNwZWNpZnlpbmcgTW9kZWwgNAoKT1RfTW9kZWw0IDwtIGxtKHRyYW5zQWNjIH4gSHVsbF9iVlNEXzI1ICsgSHVsbF9iVlNEXzc1ICsgSHVsbF9iICsgVlNBX2IsIGRhdGEgPSBBY291c3RpY0RhdGEpCgojIyBNb2RlbCA0IEFzc3VtcHRpb24gQ2hlY2sKCnBlcmZvcm1hbmNlOjpjaGVja19tb2RlbChPVF9Nb2RlbDQpCgojIyBNb2RlbCA0IFN1bW1hcnkKCnN1bW1hcnkoT1RfTW9kZWw0KQoKIyMgTW9kZWwgMyBhbmQgTW9kZWwgNCBDb21wYXJpc29uCgphbm92YShPVF9Nb2RlbDMsIE9UX01vZGVsNCkKCmBgYApNb2RlbCA1CmBgYHtyfQoKIyMgU3BlY2lmeWluZyBNb2RlbCA1CgpPVF9Nb2RlbDUgPC0gbG0odHJhbnNBY2MgfiBIdWxsX2JWU0RfMjUgKyBIdWxsX2JWU0RfNzUgKyBIdWxsX2IgKyBWU0FfYiArIHZvd2VsX0VEX2IsIGRhdGEgPSBBY291c3RpY0RhdGEpCgojIyBNb2RlbCA0IEFzc3VtcHRpb24gQ2hlY2sKCnBlcmZvcm1hbmNlOjpjaGVja19tb2RlbChPVF9Nb2RlbDUpCgojIyBNb2RlbCA0IFN1bW1hcnkKCnN1bW1hcnkoT1RfTW9kZWw1KQoKIyMgTW9kZWwgMyBhbmQgTW9kZWwgNCBDb21wYXJpc29uCgphbm92YShPVF9Nb2RlbDQsIE9UX01vZGVsNSkKCmBgYAoKCiMjIyBGaW5hbCBNb2RlbAoKYGBge3J9CgojIyBTcGVjaWZ5aW5nIEZpbmFsIE1vZGVsCgpPVF9Nb2RlbF9maW5hbCA8LSBsbSh0cmFuc0FjYyB+IFZTQV9iLCBkYXRhID0gQWNvdXN0aWNEYXRhKQoKIyMgRmluYWwgTW9kZWwgQXNzdW1wdGlvbiBDaGVjawoKcGVyZm9ybWFuY2U6OmNoZWNrX21vZGVsKE9UX01vZGVsX2ZpbmFsKQoKIyMgRmluYWwgTW9kZWwgU3VtbWFyeQoKc3VtbWFyeShPVF9Nb2RlbF9maW5hbCkKY29uZmludChPVF9Nb2RlbF9maW5hbCkKCmBgYAoKIyMgVkFTIE1vZGVscwoKTW9kZWwgMQpgYGB7cn0KCiMgU3BlY2lmeWluZyBNb2RlbCAxCgpWQVNfTW9kZWwxIDwtIGxtKFZBUyB+IEh1bGxfYlZTRF8yNSwgZGF0YSA9IEFjb3VzdGljRGF0YSkKCiMjIE1vZGVsIDEgQXNzdW1wdGlvbnMgCgpwZXJmb3JtYW5jZTo6Y2hlY2tfbW9kZWwoVkFTX01vZGVsMSkKCiMjIE1vZGVsIDEgU3VtbWFyeQoKc3VtbWFyeShWQVNfTW9kZWwxKQoKYGBgCgpNb2RlbCAyCmBgYHtyfQoKIyMgU3BlY2lmeWluZyBNb2RlbCAyCgpWQVNfTW9kZWwyIDwtIGxtKFZBUyB+IEh1bGxfYlZTRF8yNSArIEh1bGxfYlZTRF83NSwgZGF0YSA9IEFjb3VzdGljRGF0YSkKCiMjIE1vZGVsIDIgQXNzdW1wdGlvbiBDaGVjawoKcGVyZm9ybWFuY2U6OmNoZWNrX21vZGVsKFZBU19Nb2RlbDIpCgojIyBNb2RlbCAyIFN1bW1hcnkKCnN1bW1hcnkoVkFTX01vZGVsMikKCiMjIE1vZGVsIDEgYW5kIE1vZGVsIDIgQ29tcGFyaXNvbgoKYW5vdmEoVkFTX01vZGVsMSwgVkFTX01vZGVsMikKCmBgYAoKTW9kZWwgMwpgYGB7cn0KCiMjIFNwZWNpZnlpbmcgTW9kZWwgMwoKVkFTX01vZGVsMyA8LSBsbShWQVMgfiBIdWxsX2JWU0RfMjUgKyBIdWxsX2JWU0RfNzUgKyBIdWxsX2IsIGRhdGEgPSBBY291c3RpY0RhdGEpCgojIyBNb2RlbCAzIEFzc3VtcHRpb24gQ2hlY2sKCnBlcmZvcm1hbmNlOjpjaGVja19tb2RlbChWQVNfTW9kZWwzKQoKIyMgTW9kZWwgMyBTdW1tYXJ5CgpzdW1tYXJ5KFZBU19Nb2RlbDMpCgojIyBNb2RlbCAyIGFuZCBNb2RlbCAzIENvbXBhcmlzb24KCmFub3ZhKFZBU19Nb2RlbDIsIFZBU19Nb2RlbDMpCgpgYGAKCk1vZGVsIDQKYGBge3J9CgojIyBTcGVjaWZ5aW5nIE1vZGVsIDQKClZBU19Nb2RlbDQgPC0gbG0oVkFTIH4gSHVsbF9iVlNEXzI1ICsgSHVsbF9iVlNEXzc1ICsgSHVsbF9iICsgVlNBX2IsIGRhdGEgPSBBY291c3RpY0RhdGEpCgojIyBNb2RlbCA0IEFzc3VtcHRpb24gQ2hlY2sKCnBlcmZvcm1hbmNlOjpjaGVja19tb2RlbChWQVNfTW9kZWw0KQoKIyMgTW9kZWwgNCBTdW1tYXJ5CgpzdW1tYXJ5KFZBU19Nb2RlbDQpCgojIyBNb2RlbCAzIGFuZCBNb2RlbCA0IENvbXBhcmlzb24KCmFub3ZhKFZBU19Nb2RlbDMsIFZBU19Nb2RlbDQpCgpgYGAKCk1vZGVsIDUKYGBge3J9CgojIyBTcGVjaWZ5aW5nIE1vZGVsIDUKClZBU19Nb2RlbDUgPC0gbG0oVkFTIH4gSHVsbF9iVlNEXzI1ICsgSHVsbF9iVlNEXzc1ICsgSHVsbF9iICsgVlNBX2IgKyB2b3dlbF9FRF9iLCBkYXRhID0gQWNvdXN0aWNEYXRhKQoKIyMgTW9kZWwgNSBBc3N1bXB0aW9uIENoZWNrCgpwZXJmb3JtYW5jZTo6Y2hlY2tfbW9kZWwoVkFTX01vZGVsNSkKCiMjIE1vZGVsIDUgU3VtbWFyeQoKc3VtbWFyeShWQVNfTW9kZWw1KQoKIyMgTW9kZWwgNCBhbmQgTW9kZWwgNSBDb21wYXJpc29uCgphbm92YShWQVNfTW9kZWw0LCBWQVNfTW9kZWw1KQoKYGBgCgoKIyMjIEZpbmFsIE1vZGVsCgpgYGB7cn0KCiMjIFNwZWNpZnlpbmcgRmluYWwgTW9kZWwKClZBU19Nb2RlbF9maW5hbCA8LSBsbShWQVMgfiBWU0FfYiwgZGF0YSA9IEFjb3VzdGljRGF0YSkKCiMjIEZpbmFsIE1vZGVsIEFzc3VtcHRpb24gQ2hlY2sKCnBlcmZvcm1hbmNlOjpjaGVja19tb2RlbChWQVNfTW9kZWxfZmluYWwpCgojIyBGaW5hbCBNb2RlbCBTdW1tYXJ5CgpzdW1tYXJ5KFZBU19Nb2RlbF9maW5hbCkKY29uZmludChWQVNfTW9kZWxfZmluYWwpCgpgYGAKCiMgUmVzZWFyY2ggUTI6IFJlbGF0aW9uc2hpcCBiZXR3ZWVuIE9UIGFuZCBWQVMKCk1vZGVsIDEKYGBge3J9CgojIFNwZWNpZnkgTW9kZWwKCk9UX1ZBU19tb2RlbCA8LSBsbSh0cmFuc0FjYyB+IFZBUypFdGlvbG9neSArIFZBUypTZXgsIGRhdGEgPSBBY291c3RpY0RhdGEpCgojIEFzc3VtcHRpb24gQ2hlY2sKCnBlcmZvcm1hbmNlOjpjaGVja19tb2RlbChPVF9WQVNfbW9kZWwpCgojIE1vZGVsIFJlc3VsdHMKCnN1bW1hcnkoT1RfVkFTX21vZGVsKQoKYGBgCgojIyBGaW5hbCBNb2RlbAoKYGBge3J9CgojIFNwZWNpZnkgRmluYWwgTW9kZWwKCk9UX1ZBU19maW5hbCA8LSBsbSh0cmFuc0FjYyB+IFZBUywgZGF0YSA9IEFjb3VzdGljRGF0YSkKCmNvbmZpbnQoT1RfVkFTX2ZpbmFsKQoKIyBNb2RlbCBSZXN1bHRzCgpzdW1tYXJ5KE9UX1ZBU19maW5hbCkKCmBgYAoKIyBNYW51c2NyaXB0IFRhYmxlcwojI0Rlc2NyaXB0aXZlcyBUYWJsZQpgYGB7cn0KZ3REYXRhIDwtIEFjb3VzdGljRGF0YSAlPiUKICByYmluZCguLEFjb3VzdGljRGF0YSAlPiUKICAgICAgICAgIGRwbHlyOjptdXRhdGUoRXRpb2xvZ3kgPSAiQWxsIEV0aW9sb2dpZXMiKSkgJT4lCiAgcmJpbmQoLixBY291c3RpY0RhdGEgJT4lCiAgICAgICAgICByYmluZCguLEFjb3VzdGljRGF0YSAlPiUKICAgICAgICAgIGRwbHlyOjptdXRhdGUoRXRpb2xvZ3kgPSAiQWxsIEV0aW9sb2dpZXMiKSkgJT4lCiAgICAgICAgICBkcGx5cjo6bXV0YXRlKFNleCA9ICJBbGwiKSkgJT4lCiAgZHBseXI6Om11dGF0ZShTZXggPSBhcy5mYWN0b3IoU2V4KSwKICAgICAgICAgICAgICAgIEV0aW9sb2d5ID0gYXMuZmFjdG9yKEV0aW9sb2d5KSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KFNleCwgRXRpb2xvZ3kpICU+JQogIGRwbHlyOjpzdW1tYXJpemUoVlNBX21lYW4gPSBtZWFuKFZTQV9iLCBuYS5ybSA9VCksIFZTQV9zZCA9IHNkKFZTQV9iLCBuYS5ybSA9IFQpLAogICAgICAgICAgICAgICAgICAgRGlzcF9tZWFuID0gbWVhbih2b3dlbF9FRF9iLCBuYS5ybSA9VCksIERpc3Bfc2QgPSBzZCh2b3dlbF9FRF9iLCBuYS5ybSA9VCksCiAgICAgICAgICAgICAgICAgICBIdWxsX21lYW4gPSBtZWFuKEh1bGxfYiwgbmEucm0gPVQpLCBIdWxsX3NkID0gc2QoSHVsbF9iLCBuYS5ybSA9VCksCiAgICAgICAgICAgICAgICAgICBWU0QyNV9tZWFuID0gbWVhbihIdWxsX2JWU0RfMjUsIG5hLnJtID1UKSwgVlNEMjVfc2QgPSBzZChIdWxsX2JWU0RfMjUsIG5hLnJtID1UKSwKICAgICAgICAgICAgICAgICAgIFZTRDUwX21lYW4gPSBtZWFuKEh1bGxfYlZTRF81MCwgbmEucm0gPVQpLCBWU0Q1MF9zZCA9IHNkKEh1bGxfYlZTRF81MCwgbmEucm0gPVQpLAogICAgICAgICAgICAgICAgICAgVlNENzVfbWVhbiA9IG1lYW4oSHVsbF9iVlNEXzc1LCBuYS5ybSA9VCksIFZTRDc1X3NkID0gc2QoSHVsbF9iVlNEXzc1LCBuYS5ybSA9VCksCiAgICAgICAgICAgICAgICAgICBWQVNfbWVhbiA9IG1lYW4oVkFTLCBuYS5ybSA9VCksIFZBU19zZCA9IHNkKFZBUywgbmEucm0gPVQpLAogICAgICAgICAgICAgICAgICAgT1RfbWVhbiA9IG1lYW4odHJhbnNBY2MsIG5hLnJtID1UKSwgT1Rfc2QgPSBzZCh0cmFuc0FjYywgbmEucm0gPVQpKSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IFZTQV9tZWFuOk9UX3NkLCBuYW1lc190byA9ICJNZWFzdXJlIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIlZhbHVlIikgJT4lCiAgZHBseXI6Om11dGF0ZShtZWFuU0QgPSBpZmVsc2UoZ3JlcGwoIl9tZWFuIixNZWFzdXJlKSwiTSIsInNkIiksCiAgICAgICAgICAgICAgICBNZWFzdXJlID0gZ3N1YigiX21lYW4iLCIiLE1lYXN1cmUpLAogICAgICAgICAgICAgICAgTWVhc3VyZSA9IGdzdWIoIl9zZCIsIiIsTWVhc3VyZSksCiAgICAgICAgICAgICAgICBFdGlvbG9neSA9IHBhc3RlKEV0aW9sb2d5LG1lYW5TRCwgc2VwID0gIl8iKSwKICAgICAgICAgICAgICAgIFNleCA9IGNhc2Vfd2hlbigKICAgICAgICAgICAgICAgICAgU2V4ID09ICJBbGwiIH4gIkFsbCBTcGVha2VycyIsCiAgICAgICAgICAgICAgICAgIFNleCA9PSAiTSIgfiAiTWFsZSIsCiAgICAgICAgICAgICAgICAgIFNleCA9PSAiRiIgfiAiRmVtYWxlIgogICAgICAgICAgICAgICAgKSkgJT4lCiAgZHBseXI6OnNlbGVjdCghbWVhblNEKSAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gRXRpb2xvZ3ksIHZhbHVlc19mcm9tID0gIlZhbHVlIikgJT4lCiAgZHBseXI6OmZpbHRlcihNZWFzdXJlICE9ICJWU0Q1MCIpCgpndERhdGEgJT4lCiAgZ3Q6Omd0KAogICAgcm93bmFtZV9jb2wgPSAiTWVhc3VyZSIsCiAgICBncm91cG5hbWVfY29sID0gIlNleCIsCiAgKSAlPiUKICBmbXRfbnVtYmVyKAogICAgY29sdW1ucyA9ICdBbGwgRXRpb2xvZ2llc19NJzpQRF9zZCwKICAgIGRlY2ltYWxzID0gMgogICkgJT4lCiAgdGFiX3NwYW5uZXIoCiAgICBsYWJlbCA9ICJBbGwgRXRpb2xvZ2llcyIsCiAgICBjb2x1bW5zID0gYygnQWxsIEV0aW9sb2dpZXNfTScsICdBbGwgRXRpb2xvZ2llc19zZCcpCiAgKSAlPiUKICAgIHRhYl9zcGFubmVyKAogICAgbGFiZWwgPSAiQUxTIiwKICAgIGNvbHVtbnMgPSBjKEFMU19NLCBBTFNfc2QpCiAgKSAlPiUKICB0YWJfc3Bhbm5lcigKICAgIGxhYmVsID0gIlBEIiwKICAgIGNvbHVtbnMgPSBjKFBEX00sIFBEX3NkKQogICkgJT4lCiAgdGFiX3NwYW5uZXIoCiAgICBsYWJlbCA9ICJIRCIsCiAgICBjb2x1bW5zID0gYyhIRF9NLCBIRF9zZCkKICApICU+JQogIHRhYl9zcGFubmVyKAogICAgbGFiZWwgPSAiQXRheGljIiwKICAgIGNvbHVtbnMgPSBjKEF0YXhpY19NLCBBdGF4aWNfc2QpCiAgKSAlPiUKICBjb2xzX2xhYmVsKAogICAgICdBbGwgRXRpb2xvZ2llc19NJyA9ICJNIiwKICAgICAnQWxsIEV0aW9sb2dpZXNfc2QnID0gIlNEIiwKICAgICBBTFNfTSA9ICJNIiwKICAgICBBTFNfc2QgPSAiU0QiLAogICAgIFBEX00gPSAiTSIsCiAgICAgUERfc2QgPSAiU0QiLAogICAgIEhEX00gPSAiTSIsCiAgICAgSERfc2QgPSAiU0QiLAogICAgIEF0YXhpY19NID0gIk0iLAogICAgIEF0YXhpY19zZCA9ICJTRCIKICApICU+JQogIGd0c2F2ZSgiRGVzY3JpcHRpdmVzVGFibGUuaHRtbCIsIHBhdGggPSAiVGFibGVzIikKCmBgYAoKIyMgT1QgTW9kZWwKYGBge3J9CnNqUGxvdDo6dGFiX21vZGVsKE9UX01vZGVsMSxPVF9Nb2RlbDIsT1RfTW9kZWwzLCBPVF9Nb2RlbDQsIE9UX01vZGVsNSwgT1RfTW9kZWxfZmluYWwsCiAgICAgICAgICAgICAgICAgIHNob3cuY2kgPSBGLAogICAgICAgICAgICAgICAgICBwLnN0eWxlID0gInN0YXJzIiwKICAgICAgICAgICAgICAgICAgZmlsZSA9ICJUYWJsZXMvT1QgTW9kZWxzLmh0bWwiKQpgYGAKCiMjIFZBUyBNb2RlbApgYGB7cn0Kc2pQbG90Ojp0YWJfbW9kZWwoVkFTX01vZGVsMSxWQVNfTW9kZWwyLFZBU19Nb2RlbDMsIFZBU19Nb2RlbDQsIFZBU19Nb2RlbDUsIFZBU19Nb2RlbF9maW5hbCwKICAgICAgICAgICAgICAgICAgc2hvdy5jaSA9IEYsCiAgICAgICAgICAgICAgICAgIHAuc3R5bGUgPSAic3RhcnMiLAogICAgICAgICAgICAgICAgICBmaWxlID0gIlRhYmxlcy9WQVMgTW9kZWxzLmh0bWwiKQpgYGAKCiMjIE9UIHZzLiBWQVMKYGBge3J9CnNqUGxvdDo6dGFiX21vZGVsKE9UX1ZBU19tb2RlbCxPVF9WQVNfZmluYWwsCiAgICAgICAgICAgICAgICAgIHNob3cuY2kgPSBGLAogICAgICAgICAgICAgICAgICBzaG93LnJlZmx2bCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgIHAuc3R5bGUgPSAic3RhcnMiLAogICAgICAgICAgICAgICAgICBmaWxlID0gIlRhYmxlcy9PVCBhbmQgVkFTIENvbXBhcmlzb24uaHRtbCIpCmBgYAoKIyBNYW51c2NyaXB0IEZpZ3VyZXMKIyMgRXhhbXBsZSBNZWFzdXJlcwpgYGB7cn0KZm9ybWFudENvbG9yIDwtICJncmV5Igpmb3JtYW50QWxwaGEgPC0gLjk1CmxpbmVDb2xvciA8LSAid2hpdGUiCmxpbmVBbHBoYSA8LSAuOAoKdm93ZWxEYXRhIDwtIHJpbzo6aW1wb3J0KCJQcmVwcGVkIERhdGEvVm93ZWwgRGF0YS5jc3YiKSAlPiUKICBkcGx5cjo6ZmlsdGVyKFNwZWFrZXIgPT0gIkFGOCIpCgogIFBpdGNoX1BSQUFUIDwtIGxpc3QuZmlsZXMocGF0aCA9IHBhc3RlKCJQcmVwcGVkIERhdGEvRXhhbXBsZSBEYXRhLyIsIHNlcCA9ICIiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiLlBpdGNoIiwgaWdub3JlLmNhc2UgPSBUKSAlPiUKICAgIHBhc3RlKCJQcmVwcGVkIERhdGEvRXhhbXBsZSBEYXRhLyIsLiwgc2VwID0gIiIpICU+JQogICAgcmVhZC5kZWxpbSguLCBoZWFkZXIgPSBGKSAlPiUKICAgIGRwbHlyOjpyZW5hbWUoUGl0Y2ggPSBWMSkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKFBpdGNoID0gZ3N1YigiLS11bmRlZmluZWQtLSIsTkEsUGl0Y2gpLAogICAgICAgICAgICAgICAgICBQaXRjaCA9IGFzLm51bWVyaWMoUGl0Y2gpKQogIAogIEZvcm1hbnRzX1BSQUFUIDwtIGxpc3QuZmlsZXMocGF0aCA9IHBhc3RlKCJQcmVwcGVkIERhdGEvRXhhbXBsZSBEYXRhLyIsIHNlcCA9ICIiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiX0Zvcm1hbnQiLCBpZ25vcmUuY2FzZSA9IFQpICU+JQogICAgcGFzdGUoIlByZXBwZWQgRGF0YS9FeGFtcGxlIERhdGEvIiwuLCBzZXAgPSAiIikgJT4lCiAgICByZWFkLmRlbGltKC4sIGhlYWRlciA9IFQpICU+JQogICAgZHBseXI6OnNlbGVjdCghYyhuZm9ybWFudHMsIEIxLkh6LiwgQjIuSHouLCBCMy5Iei4sIEY0Lkh6LiwgQjQuSHouLCBGNS5Iei4sIEI1Lkh6LikpICU+JQogICAgZHBseXI6OnJlbmFtZShUaW1lX3MgPSB0aW1lLnMuLAogICAgICAgICAgICAgICAgICBGMV9IeiA9IEYxLkh6LiwKICAgICAgICAgICAgICAgICAgRjJfSHogPSBGMi5Iei4sCiAgICAgICAgICAgICAgICAgIEYzX0h6ID0gRjMuSHouKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoRjFfSHogPSBpZmVsc2UoRjFfSHogPT0gMCwgTkEsIEYxX0h6KSwKICAgICAgICAgICAgICAgICAgRjJfSHogPSBpZmVsc2UoRjJfSHogPT0gMCwgTkEsIEYyX0h6KSwKICAgICAgICAgICAgICAgICAgRjNfSHogPSBpZmVsc2UoRjNfSHogPT0gMCwgTkEsIEYzX0h6KSkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKEYxX0h6ID0gYXMubnVtZXJpYyhGMV9IeiksCiAgICAgICAgICAgICAgICAgIEYyX0h6ID0gYXMubnVtZXJpYyhGMl9IeiksCiAgICAgICAgICAgICAgICAgIEYzX0h6ID0gc3VwcHJlc3NXYXJuaW5ncyhhcy5udW1lcmljKEYzX0h6KSksCiAgICAgICAgICAgICAgICAgIFRpbWVfbXMgPSBUaW1lX3MgLyAxMDAwLAogICAgICAgICAgICAgICAgICBGMV9rSHogPSBGMV9IeiAvIDEwMDAsCiAgICAgICAgICAgICAgICAgIEYyX2tIeiA9IEYyX0h6IC8gMTAwMCwKICAgICAgICAgICAgICAgICAgRjNfa0h6ID0gRjNfSHogLyAxMDAwKSAlPiUKICAgIGRwbHlyOjpzZWxlY3QoIVRpbWVfcykgJT4lCiAgICBkcGx5cjo6cmVsb2NhdGUoVGltZV9tcywgLmJlZm9yZSA9IEYxX0h6KSAlPiUKICAgIGNiaW5kKC4sUGl0Y2hfUFJBQVQpCiAgCiAgYyA8LSAyCiAgd2hpbGUoYyA8IE5ST1coRm9ybWFudHNfUFJBQVQpKXsKICAgIEZvcm1hbnRzX1BSQUFUJEYxX0h6W2NdIDwtIGlmZWxzZShpcy5uYShGb3JtYW50c19QUkFBVCRGMV9IeltjLTFdKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMubmEoRm9ybWFudHNfUFJBQVQkRjFfSHpbYysxXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybWFudHNfUFJBQVQkRjFfSHpbY10pCiAgICBGb3JtYW50c19QUkFBVCRGMl9IeltjXSA8LSBpZmVsc2UoaXMubmEoRm9ybWFudHNfUFJBQVQkRjJfSHpbYy0xXSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzLm5hKEZvcm1hbnRzX1BSQUFUJEYyX0h6W2MrMV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcm1hbnRzX1BSQUFUJEYyX0h6W2NdKQogICAgYyA8LSBjICsgMQogIH0KICBybShjKQogIAogIEZvcm1hbnRzX1BSQUFUIDwtIEZvcm1hbnRzX1BSQUFUICU+JQogICAgZHBseXI6OmZpbHRlcighaXMubmEoUGl0Y2gpKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoRjFfbWFkID0gKGFicyhGMV9IeiAtIG1lZGlhbihGMV9IeikpLyBtYWQoRjFfSHosIGNvbnN0YW50ID0gMS40ODI2KSkgPiAyLjUsCiAgICAgICAgICAgICAgICAgIEYyX21hZCA9IChhYnMoRjJfSHogLSBtZWRpYW4oRjJfSHopKS8gbWFkKEYyX0h6LCBjb25zdGFudCA9IDEuNDgyNikpID4gMi41KSAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoRjFfbWFkID09IEZBTFNFICYgRjJfbWFkID09IEZBTFNFKSAlPiUKICAgIGRwbHlyOjptdXRhdGUobURpc3QgPSBtYWhhbGFub2JpcyhjYmluZCguJEYxX0h6LCAuJEYyX0h6KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xNZWFucyhjYmluZCguJEYxX0h6LCAuJEYyX0h6KSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY292ID0gY292KGNiaW5kKC4kRjFfSHosIC4kRjJfSHopKSksCiAgICAgICAgICAgICAgICAgIG1EaXN0X3NkID0gYWJzKHNjYWxlKG1EaXN0LGNlbnRlciA9IFQpKSkgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKG1EaXN0X3NkIDwgMikgJT4lCiAgICBkcGx5cjo6c2VsZWN0KCFjKEYxX21hZCwgRjJfbWFkLCBtRGlzdCwgbURpc3Rfc2QpKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoRjFfeiA9IHNjYWxlKEYxX0h6LCBjZW50ZXIgPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgRjJfeiA9IHNjYWxlKEYyX0h6LCBjZW50ZXIgPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgRjNfeiA9IHNjYWxlKEYzX0h6LCBjZW50ZXIgPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgRjFfYiA9IGVtdVI6OmJhcmsoRjFfSHopLAogICAgICAgICAgICAgICAgICBGMl9iID0gZW11Ujo6YmFyayhGMl9IeiksCiAgICAgICAgICAgICAgICAgIEYzX2IgPSBlbXVSOjpiYXJrKEYzX0h6KSkKICAKICBybShQaXRjaF9QUkFBVCkKICAKICAKIyMgQ29ybmVyIERpc3BlcnNpb24gLS0tLQogIHdlZGdlIDwtIHZvd2VsRGF0YSAlPiUKICAgIGRwbHlyOjpncm91cF9ieShWb3dlbCkgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKG1lYW5fRjEgPSBtZWFuKEYxX3RlbXBNaWQpLAogICAgICAgICAgICAgIG1lYW5fRjIgPSBtZWFuKEYyX3RlbXBNaWQpLAogICAgICAgICAgICAgIG1lYW5fRjFfeiA9IG1lYW4oRjFfel90ZW1wTWlkKSwKICAgICAgICAgICAgICBtZWFuX0YyX3ogPSBtZWFuKEYyX3pfdGVtcE1pZCksCiAgICAgICAgICAgICAgbWVhbl9GMV9iID0gbWVhbihGMV9iX3RlbXBNaWQpLAogICAgICAgICAgICAgIG1lYW5fRjJfYiA9IG1lYW4oRjJfYl90ZW1wTWlkKSkgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKFZvd2VsID09ICJ2IikKICAgIAogIGNvcm5lcl9kaXMgPC0gdm93ZWxEYXRhICU+JQogICAgZHBseXI6OmZpbHRlcihWb3dlbCAhPSAidiIpICU+JQogICAgZHBseXI6Omdyb3VwX2J5KFZvd2VsKSAlPiUKICAgIGRwbHlyOjpzdW1tYXJpemUobWVhbl9GMSA9IG1lYW4oRjFfdGVtcE1pZCksCiAgICAgICAgICAgICAgbWVhbl9GMiA9IG1lYW4oRjJfdGVtcE1pZCksCiAgICAgICAgICAgICAgbWVhbl9GMV96ID0gbWVhbihGMV96X3RlbXBNaWQpLAogICAgICAgICAgICAgIG1lYW5fRjJfeiA9IG1lYW4oRjJfel90ZW1wTWlkKSwKICAgICAgICAgICAgICBtZWFuX0YxX2IgPSBtZWFuKEYxX2JfdGVtcE1pZCksCiAgICAgICAgICAgICAgbWVhbl9GMl9iID0gbWVhbihGMl9iX3RlbXBNaWQpKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoVm93ZWxfRUQgPSBzcXJ0KChtZWFuX0YxLXdlZGdlJG1lYW5fRjEpXjIgKyAobWVhbl9GMi13ZWRnZSRtZWFuX0YyKV4yKSwKICAgICAgICAgICAgICAgICAgVm93ZWxfRURfeiA9IHNxcnQoKG1lYW5fRjFfei13ZWRnZSRtZWFuX0YxX3opXjIgKyAobWVhbl9GMl96LXdlZGdlJG1lYW5fRjJfeileMiksCiAgICAgICAgICAgICAgICAgIFZvd2VsX0VEX2IgPSBzcXJ0KChtZWFuX0YxX2Itd2VkZ2UkbWVhbl9GMV9iKV4yICsgKG1lYW5fRjJfYi13ZWRnZSRtZWFuX0YyX2IpXjIpKQoKICAgIAojIFBsb3QgQ29ybmVyIERpc3BlcnNpb24KICAgICAgIyBDaGFuZ2luZyB0byBJUEEgc3ltYm9scwogICAgICBjb3JuZXJfZGlzIDwtIGNvcm5lcl9kaXMgJT4lCiAgICAgICAgZHBseXI6Om11dGF0ZShWb3dlbCA9IGRwbHlyOjpjYXNlX3doZW4oCiAgICAgICAgICBWb3dlbCA9PSAiYWUiIH4gIsOmIiwKICAgICAgICAgIFRSVUUgfiBWb3dlbAogICAgICAgICkpCiAgICAgIAogICAgICB3ZWRnZSA8LSB3ZWRnZSAlPiUKICAgICAgICBkcGx5cjo6bXV0YXRlKFZvd2VsID0gY2FzZV93aGVuKAogICAgICAgICAgVm93ZWwgPT0gInYiIH4gIsqMIiwKICAgICAgICAgIFRSVUUgfiBWb3dlbAogICAgICAgICkpCiAgICAgIAogICAgICBDRHBsb3QgPC0gZ2dwbG90KGFlcyh4PUYyX2IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9RjFfYiksCiAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IEZvcm1hbnRzX1BSQUFULAogICAgICAgICAgICAgICAgICAgICAgIGluaGVyaXQuYWVzID0gRkFMU0UpICsgCiAgICAgIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwKICAgICAgICAgICAgICAgICBhbHBoYSA9IGZvcm1hbnRBbHBoYSwKICAgICAgICAgICAgICAgICBjb2xvciA9IGZvcm1hbnRDb2xvcikgKyAKICAgICAgZ2VvbV9saW5lKGFlcyh4ID0gbWVhbl9GMl9iLAogICAgICAgICAgICAgICAgICAgIHkgPSBtZWFuX0YxX2IpLAogICAgICAgICAgICAgICAgZGF0YSA9IGNvcm5lcl9kaXMgJT4lCiAgICAgICAgICAgICAgICAgIGRwbHlyOjpzZWxlY3QoVm93ZWw6bWVhbl9GMl9iKSAlPiUKICAgICAgICAgICAgICAgICAgZHBseXI6OmZpbHRlcihWb3dlbCA9PSAiaSIpICU+JQogICAgICAgICAgICAgICAgICByYmluZCguLHdlZGdlKSwKICAgICAgICAgICAgICAgIGNvbG9yID0gbGluZUNvbG9yLAogICAgICAgICAgICAgICAgc2l6ZSA9IDEuNSwKICAgICAgICAgICAgICAgIGFscGhhID0gbGluZUFscGhhKSArCiAgICAgIGdlb21fbGluZShhZXMoeCA9IG1lYW5fRjJfYiwKICAgICAgICAgICAgICAgICAgICB5ID0gbWVhbl9GMV9iKSwKICAgICAgICAgICAgICAgIGRhdGEgPSBjb3JuZXJfZGlzICU+JQogICAgICAgICAgICAgICAgICBkcGx5cjo6c2VsZWN0KFZvd2VsOm1lYW5fRjJfYikgJT4lCiAgICAgICAgICAgICAgICAgIGRwbHlyOjpmaWx0ZXIoVm93ZWwgPT0gImEiKSAlPiUKICAgICAgICAgICAgICAgICAgcmJpbmQoLix3ZWRnZSksCiAgICAgICAgICAgICAgICBjb2xvciA9IGxpbmVDb2xvciwKICAgICAgICAgICAgICAgIHNpemUgPSAxLjUsCiAgICAgICAgICAgICAgICBhbHBoYSA9IGxpbmVBbHBoYSkgKwogICAgICBnZW9tX2xpbmUoYWVzKHggPSBtZWFuX0YyX2IsCiAgICAgICAgICAgICAgICAgICAgeSA9IG1lYW5fRjFfYiksCiAgICAgICAgICAgICAgICBkYXRhID0gY29ybmVyX2RpcyAlPiUKICAgICAgICAgICAgICAgICAgZHBseXI6OnNlbGVjdChWb3dlbDptZWFuX0YyX2IpICU+JQogICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKFZvd2VsID09ICLDpiIpICU+JQogICAgICAgICAgICAgICAgICByYmluZCguLHdlZGdlKSwKICAgICAgICAgICAgICAgIGNvbG9yID0gbGluZUNvbG9yLAogICAgICAgICAgICAgICAgc2l6ZSA9IDEuNSwKICAgICAgICAgICAgICAgIGFscGhhID0gbGluZUFscGhhKSArCiAgICAgIGdlb21fbGluZShhZXMoeCA9IG1lYW5fRjJfYiwKICAgICAgICAgICAgICAgICAgICB5ID0gbWVhbl9GMV9iKSwKICAgICAgICAgICAgICAgIGRhdGEgPSBjb3JuZXJfZGlzICU+JQogICAgICAgICAgICAgICAgICBkcGx5cjo6c2VsZWN0KFZvd2VsOm1lYW5fRjJfYikgJT4lCiAgICAgICAgICAgICAgICAgIGRwbHlyOjpmaWx0ZXIoVm93ZWwgPT0gInUiKSAlPiUKICAgICAgICAgICAgICAgICAgcmJpbmQoLix3ZWRnZSksCiAgICAgICAgICAgICAgICBjb2xvciA9IGxpbmVDb2xvciwKICAgICAgICAgICAgICAgIHNpemUgPSAxLjUsCiAgICAgICAgICAgICAgICBhbHBoYSA9IGxpbmVBbHBoYSkgKwogICAgICBnZW9tX3BvaW50KGFlcyh4ID0gbWVhbl9GMl9iLAogICAgICAgICAgICAgICAgICAgICB5ID0gbWVhbl9GMV9iLAogICAgICAgICAgICAgICAgICAgICBjb2xvciA9IFZvd2VsKSwKICAgICAgICAgICAgICAgICBkYXRhID0gY29ybmVyX2RpcyAlPiUKICAgICAgICAgICAgICAgICAgZHBseXI6OnNlbGVjdChWb3dlbDptZWFuX0YyX2IpICU+JQogICAgICAgICAgICAgICAgICByYmluZCguLHdlZGdlKSwKICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgIHNpemUgPSA1KSArCiAgICAgIHNjYWxlX3lfcmV2ZXJzZSgpICsKICAgICAgc2NhbGVfeF9yZXZlcnNlKCkgKwogICAgICB0aGVtZV9jbGFzc2ljKCkgKyBsYWJzKHRpdGxlID0gcGFzdGUoIkNvcm5lciBEaXNwZXJzaW9uIikpICsgeGxhYigiRjIgKGJhcmspIikgKyB5bGFiKCJGMSAoYmFyaykiKSArCiAgICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgICAgICAgICBhc3BlY3QucmF0aW8gPSAxKSArCiAgICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiYSIgPSAiIzFBQUQ3NyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiw6YiID0gIiMxMjc5QjUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImkiID0gIiNGRkJGMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInUiID0gIiNGRDc4NTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIsqMIiA9ICIjQkYzMTc4IikpCiAgICBDRHBsb3QKICAgIAogICAgICBybShjb3JuZXJfZGlzLCB3ZWRnZSkKICAgICAgCiMjIFZvd2VsIFNwYWNlIEFyZWEgLS0tLQogIFZTQV9jb29yZHMgPC0gdm93ZWxEYXRhICU+JQogICAgZHBseXI6OmZpbHRlcihWb3dlbCAhPSAidiIpICU+JQogICAgZHBseXI6Omdyb3VwX2J5KFZvd2VsKSAlPiUKICAgIGRwbHlyOjpzdW1tYXJpemUobWVhbl9GMSA9IG1lYW4oRjFfdGVtcE1pZCksCiAgICAgICAgICAgICAgbWVhbl9GMiA9IG1lYW4oRjJfdGVtcE1pZCksCiAgICAgICAgICAgICAgbWVhbl9GMV96ID0gbWVhbihGMV96X3RlbXBNaWQpLAogICAgICAgICAgICAgIG1lYW5fRjJfeiA9IG1lYW4oRjJfel90ZW1wTWlkKSwKICAgICAgICAgICAgICBtZWFuX0YxX2IgPSBtZWFuKEYxX2JfdGVtcE1pZCksCiAgICAgICAgICAgICAgbWVhbl9GMl9iID0gbWVhbihGMl9iX3RlbXBNaWQpKSAKICAKIyMjIFBsb3R0aW5nIFZTQQogICAgVlNBX2Nvb3JkcyA8LSBWU0FfY29vcmRzICU+JQogICAgICAgIGRwbHlyOjptdXRhdGUoVm93ZWwgPSBjYXNlX3doZW4oCiAgICAgICAgICBWb3dlbCA9PSAiYWUiIH4gIsOmIiwKICAgICAgICAgIFRSVUUgfiBWb3dlbAogICAgICAgICkpCiAgICAKICAgIFZTQXBsb3QgPC0gZ2dwbG90KGFlcyh4ID0gRjJfYiwKICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gRjFfYiksCiAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gRm9ybWFudHNfUFJBQVQsCiAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSArIAogICAgICBnZW9tX3BvaW50KHNoYXBlID0gMjEsCiAgICAgICAgICAgICAgICAgYWxwaGEgPSBmb3JtYW50QWxwaGEsCiAgICAgICAgICAgICAgICAgY29sb3IgPSBmb3JtYW50Q29sb3IpICsgCiAgICAgIGdlb21fcG9seWdvbihhZXMoeCA9IG1lYW5fRjJfYiwKICAgICAgICAgICAgICAgICAgICAgICB5ID0gbWVhbl9GMV9iKSwKICAgICAgICAgICAgICAgICAgIGRhdGEgPSBWU0FfY29vcmRzLAogICAgICAgICAgICAgICAgICAgYWxwaGEgPSBsaW5lQWxwaGEsCiAgICAgICAgICAgICAgICAgICBjb2xvciA9IGxpbmVDb2xvciwKICAgICAgICAgICAgICAgICAgIGZpbGw9TkEsCiAgICAgICAgICAgICAgICAgICBzaXplID0gMS41KSArCiAgICAgIGdlb21fcG9pbnQoYWVzKHggPSBtZWFuX0YyX2IsCiAgICAgICAgICAgICAgICAgICAgIHkgPSBtZWFuX0YxX2IsCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gVm93ZWwpLAogICAgICAgICAgICAgICAgIGRhdGEgPSBWU0FfY29vcmRzLAogICAgICAgICAgICAgICAgIGluaGVyaXQuYWVzID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgc2l6ZSA9IDUpICsKICAgICAgc2NhbGVfeV9yZXZlcnNlKCkgKwogICAgICBzY2FsZV94X3JldmVyc2UoKSArCiAgICAgIGd1aWRlcyhjb2xvciA9IEZBTFNFKSArCiAgICAgIHRoZW1lX2NsYXNzaWMoKSArIGxhYnModGl0bGUgPSAiVlNBIikgKyB4bGFiKCJGMiAoYmFyaykiKSArIHlsYWIoIkYxIChiYXJrKSIpICsKICAgICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgICAgIGFzcGVjdC5yYXRpbyA9IDEpICsKICAgICAgICAgICAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJhIiA9ICIjMUFBRDc3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICLDpiIgPSAiIzEyNzlCNSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaSIgPSAiI0ZGQkYwMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidSIgPSAiI0ZENzg1MyIpKQogICAgVlNBcGxvdAogIAogIHJtKFZTQV9jb29yZHMpCiAgCiMjIEh1bGwgLS0tLQoKIyMjIFBsb3R0aW5nIEh1bGwKICAgICAgY29udmV4Q29vcmRzIDwtIEZvcm1hbnRzX1BSQUFUICU+JQogICAgICAgIGRwbHlyOjpzZWxlY3QoRjFfYiwgRjJfYikgJT4lCiAgICAgICAgYXMubWF0cml4KCkgJT4lCiAgICAgICAgZ3JEZXZpY2VzOjpjaHVsbCgpCiAgICAgIGNvbnZleCA8LSBGb3JtYW50c19QUkFBVCAlPiUKICAgICAgICBzbGljZShjb252ZXhDb29yZHMpCgogICAgICBodWxsUGxvdCA8LSBnZ3Bsb3QoYWVzKEYyX2IsIEYxX2IpLAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IEZvcm1hbnRzX1BSQUFUKSArCiAgICAgICAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLAogICAgICAgICAgICAgICAgIGFscGhhID0gZm9ybWFudEFscGhhLAogICAgICAgICAgICAgICAgIGNvbG9yID0gZm9ybWFudENvbG9yKSArCiAgICAgICAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBjb252ZXgsCiAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gLjUsCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIiMxMjc5QjUiLAogICAgICAgICAgICAgICAgICAgICBmaWxsID0gTkEsCiAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAxLjUpICsKICAgICAgICBzY2FsZV95X3JldmVyc2UoKSArCiAgICAgICAgc2NhbGVfeF9yZXZlcnNlKCkgKwogICAgICAgIHRoZW1lX2NsYXNzaWMoKSArIGxhYnModGl0bGUgPSAiVlNBIEh1bGwiKSArIHhsYWIoIkYyIChiYXJrKSIpICsgeWxhYigiRjEgKGJhcmspIikgKwogICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICAgICAgYXNwZWN0LnJhdGlvID0gMSkKICAgICAgaHVsbFBsb3QKICAgIAogIAojIyBWb3dlbCBTcGFjZSBEZW5zaXR5IC0tLS0KCiMjIEJhcmsgTm9ybWFsaXplZCBEZW5zaXR5IC0tLS0KIyBzZWxlY3RpbmcgdGhlIGJhbmR3aWR0aApIX2hwaSA8LSBrczo6SHBpKHggPSBGb3JtYW50c19QUkFBVFssYygiRjJfYiIsIkYxX2IiKV0sIHBpbG90ID0gInNhbXNlIiwgcHJlID0gInNjYWxlIiwgYmlubmVkID0gVCkKCiMgY29tcHV0ZSAyZCBrZGUKayA8LSBrZGUoeCA9IEZvcm1hbnRzX1BSQUFUWyxjKCJGMl9iIiwiRjFfYiIpXSwKICAgICAgICAgSCA9IEhfaHBpLAogICAgICAgICBiaW5uZWQgPSBULAogICAgICAgICBncmlkc2l6ZSA9IDI1MCkKCiNkZW5zaXR5IDwtIGtbWyJlc3RpbWF0ZSJdXQoKIyBCZWZvcmUgd2UgY2FuIHBsb3QgdGhlIGRlbnNpdHkgZXN0aW1hdGUgd2UgbmVlZCB0byBtZWx0IGl0IGludG8gbG9uZyBmb3JtYXQKbWF0Lm1lbHRlZCA8LSBkYXRhLnRhYmxlOjptZWx0KGskZXN0aW1hdGUpCm5hbWVzKG1hdC5tZWx0ZWQpIDwtIGMoIngiLCAieSIsICJkZW5zaXR5IikKCiMgV2UgbmVlZCB0byBhZGQgdHdvIG1vcmUgY29sdW1zIHRvIHByZXNlcnZlIHRoZSBheGVzIHVuaXRzCm1hdC5tZWx0ZWQkRjIuYiA8LSByZXAoayRldmFsLnBvaW50c1tbMV1dLCB0aW1lcyA9IG5yb3coayRlc3RpbWF0ZSkpCm1hdC5tZWx0ZWQkRjEuYiA8LSByZXAoayRldmFsLnBvaW50c1tbMl1dLCBlYWNoID0gbnJvdyhrJGVzdGltYXRlKSkKbWF0Lm1lbHRlZCRkZW5zaXR5IDwtIHNjYWxlczo6cmVzY2FsZShtYXQubWVsdGVkJGRlbnNpdHksIHRvID0gYygwLCAxKSkKCiMgVlNEIC0gMjUKblZTRF8yNSA8LSBtYXQubWVsdGVkICU+JQogIGRwbHlyOjpmaWx0ZXIoZGVuc2l0eSA+IC4yNSkgJT4lCiAgZHBseXI6OnNlbGVjdChGMi5iLEYxLmIsIGRlbnNpdHkpICU+JQogIGRwbHlyOjpyZW5hbWUoRGVuc2l0eSA9IGRlbnNpdHkpCgpjb252ZXhDb29yZHMgPC0gblZTRF8yNSAlPiUKICBkcGx5cjo6c2VsZWN0KEYyLmIsIEYxLmIpICU+JQogIGFzLm1hdHJpeCgpICU+JQogICNnckRldmljZXM6Onh5LmNvb3JkcygpICU+JQogIGdyRGV2aWNlczo6Y2h1bGwoKQpuY29udmV4XzI1IDwtIG5WU0RfMjUgJT4lCiAgc2xpY2UoY29udmV4Q29vcmRzKQoKIyBWU0QgLSA3NQpuVlNEXzc1IDwtIG1hdC5tZWx0ZWQgJT4lCiAgZHBseXI6OmZpbHRlcihkZW5zaXR5ID4gLjc1KSAlPiUKICBkcGx5cjo6c2VsZWN0KEYyLmIsRjEuYiwgZGVuc2l0eSkgJT4lCiAgZHBseXI6OnJlbmFtZShEZW5zaXR5ID0gZGVuc2l0eSkKCmNvbnZleENvb3JkcyA8LSBuVlNEXzc1ICU+JQogIGRwbHlyOjpzZWxlY3QoRjIuYiwgRjEuYikgJT4lCiAgYXMubWF0cml4KCkgJT4lCiAgZ3JEZXZpY2VzOjpjaHVsbCgpCm5jb252ZXhfNzUgPC0gblZTRF83NSAlPiUKICBzbGljZShjb252ZXhDb29yZHMpCgojIFBsb3R0aW5nIFogTm9ybWFsaXplZCBWU0QgCiAgICByZiA8LSBjb2xvclJhbXBQYWxldHRlKHJldihSQ29sb3JCcmV3ZXI6OmJyZXdlci5wYWwoMTEsICJTcGVjdHJhbCIpKSkKICAgIHIgPC0gcmYoMzIpCiAgICAKICAgIHBsb3REYXRhIDwtIG1hdC5tZWx0ZWQgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpyZW5hbWUoRGVuc2l0eSA9IGRlbnNpdHkpICU+JQogICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6bXV0YXRlKFZTRGxhYmVsID0gZHBseXI6OmNhc2Vfd2hlbigKICAgICAgICAgICAgICAgICAgICAgICAgICBEZW5zaXR5IDwgLjI1IH4gIm5vbmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgIERlbnNpdHkgPiAuMjUgJiYgRGVuc2l0eSA8IC43NSB+ICJWU0QyNSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICJWU0Q3NSIKICAgICAgICAgICAgICAgICAgICAgICAgKSkKCiAgICBWU0RwbG90IDwtIGdncGxvdChkYXRhID0gcGxvdERhdGEsCiAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IEYyLmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IEYxLmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IERlbnNpdHkpKSArIAogICAgICBnZW9tX3RpbGUoKSArIAogICAgICBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsKICAgICAgI3NjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG91cnMgPSByKSArCiAgICAgIHNjYWxlX3hfcmV2ZXJzZShleHBhbmQgPSBjKDAsIDApLCAKICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHJvdW5kKHNlcShtaW4obWF0Lm1lbHRlZCRGMi5iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KG1hdC5tZWx0ZWQkRjIuYikpKSkgKwogICAgICBzY2FsZV95X3JldmVyc2UoZXhwYW5kID0gYygwLCAwKSwKICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHJvdW5kKHNlcShtaW4obWF0Lm1lbHRlZCRGMS5iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgobWF0Lm1lbHRlZCRGMS5iKSkpKSArIAogICAgICB5bGFiKCJGMSAoYmFyaykiKSArIHhsYWIoIkYyIChiYXJrKSIpICsKICAgICAgbGFicyh0aXRsZSA9ICJWU0QgSHVsbCIpICsKICAgICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgICAgIGFzcGVjdC5yYXRpbyA9IDEpICsKICAgICAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBuY29udmV4XzI1LCBhbHBoYSA9IGxpbmVBbHBoYSwgY29sb3IgPSBsaW5lQ29sb3IsIHNpemUgPSAxLjUsIGZpbGwgPSBOQSkgKwogICAgICBnZW9tX3BvbHlnb24oZGF0YSA9IG5jb252ZXhfNzUsIGFscGhhID0gbGluZUFscGhhLCBjb2xvciA9IGxpbmVDb2xvciwgc2l6ZSA9IDEuNSwgZmlsbCA9IE5BKSArCiAgICAgIGdlb21fdGV4dGN1cnZlKGRhdGEgPSBkYXRhLmZyYW1lKHggPSAxMC4zODI0NTIsIHhlbmQgPSA4LjMxMzUxNSwgeSA9IDIuODc0OTY3LCB5ZW5kID0gNC4xMjc5MTksIERlbnNpdHkgPSAxKSwgCiAgICAgICAgICAgICAgICAgYWVzKHgsIHksIHhlbmQgPSB4ZW5kLCB5ZW5kID0geWVuZCksCiAgICAgICAgICAgICAgICAgaGp1c3QgPSAwLjUsCiAgICAgICAgICAgICAgICAgdmp1c3QgPSAtLjYsCiAgICAgICAgICAgICAgICAgY3VydmF0dXJlID0gMCwKICAgICAgICAgICAgICAgICBsYWJlbCA9ICJWU0QgMjUiLAogICAgICAgICAgICAgICAgIHRleHRfb25seSA9IFQsCiAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgIHJpY2ggPSBUUlVFKSArCiAgICAgICAgZ2VvbV90ZXh0Y3VydmUoZGF0YSA9IGRhdGEuZnJhbWUoeCA9IDE0LjkyNTEyLCB4ZW5kID0gMTIuMDQ2NjAsIHkgPSAzLjc3ODI1OCwgeWVuZCA9IDUuNzU5NjcyLCBEZW5zaXR5ID0gMSksIAogICAgICAgICAgICAgICAgIGFlcyh4LCB5LCB4ZW5kID0geGVuZCwgeWVuZCA9IHllbmQpLAogICAgICAgICAgICAgICAgIGhqdXN0ID0gMC4zLCAKICAgICAgICAgICAgICAgICB2anVzdCA9IC0uNiwKICAgICAgICAgICAgICAgICBjdXJ2YXR1cmUgPSAwLAogICAgICAgICAgICAgICAgIGxhYmVsID0gIlZTRCA3NSIsCiAgICAgICAgICAgICAgICAgdGV4dF9vbmx5ID0gVCwKICAgICAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIpCiAgICAgVlNEcGxvdAogICAgClZTRDEgPC0gZ2dwbG90KGRhdGEgPSBtYXQubWVsdGVkICU+JQogICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6cmVuYW1lKERlbnNpdHkgPSBkZW5zaXR5KSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Om11dGF0ZShWU0RsYWJlbCA9IGNhc2Vfd2hlbigKICAgICAgICAgICAgICAgICAgICAgICAgICBEZW5zaXR5IDwgLjI1IH4gIm5vbmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgIERlbnNpdHkgPiAuMjUgJiYgRGVuc2l0eSA8IC43NSB+ICJWU0QyNSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICJWU0Q3NSIKICAgICAgICAgICAgICAgICAgICAgICAgKSksCiAgICAgICAgICAgICAgICAgICAgIGFlcyhGMi5iLCBGMS5iLCB6ID0gRGVuc2l0eSkpICsKICBnZW9tX2NvbnRvdXJfZmlsbGVkKGJpbnMgPSA4KSArCiAgICAgICAgc2NhbGVfeF9yZXZlcnNlKGV4cGFuZCA9IGMoMCwgMCksIAogICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gcm91bmQoc2VxKG1pbihtYXQubWVsdGVkJEYyLmIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXgobWF0Lm1lbHRlZCRGMi5iKSkpKSArCiAgICAgIHNjYWxlX3lfcmV2ZXJzZShleHBhbmQgPSBjKDAsIDApLAogICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gcm91bmQoc2VxKG1pbihtYXQubWVsdGVkJEYxLmIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heChtYXQubWVsdGVkJEYxLmIpKSkpICsKICAgICAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBuY29udmV4XzI1LCBhbHBoYSA9IGxpbmVBbHBoYSwgY29sb3IgPSBsaW5lQ29sb3IsIHNpemUgPSAxLjUsIGZpbGwgPSBOQSkgKwogICAgICBnZW9tX3BvbHlnb24oZGF0YSA9IG5jb252ZXhfNzUsIGFscGhhID0gbGluZUFscGhhLCBjb2xvciA9IGxpbmVDb2xvciwgc2l6ZSA9IDEuNSwgZmlsbCA9IE5BKSArCiAgdGhlbWUoYXNwZWN0LnJhdGlvID0gMSkKVlNEMQoKCiMgQ29tYmluZWQgUGxvdAoKbWVhc3VyZXNQbG90IDwtIFZTQXBsb3QgKyBDRHBsb3QgKyBodWxsUGxvdCArIFZTRHBsb3QgKwogICAgICBwYXRjaHdvcms6OnBsb3RfbGF5b3V0KGd1aWRlcyA9ICdjb2xsZWN0JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuY29sID0gMikKCmdnc2F2ZShmaWxlbmFtZSA9ICJQbG90cy9NZWFzdXJlcy5wbmciLAogICAgICAgcGxvdCA9IG1lYXN1cmVzUGxvdCwKICAgICAgIGhlaWdodCA9IDcsCiAgICAgICB3aWR0aCA9IDgsCiAgICAgICBzY2FsZSA9IC44KQoKYGBgCgojIyBGaWx0ZXJpbmcgUHJvY2VzcwpgYGB7cn0KZm9ybWFudEFscGhhIDwtIC4yMApteVBhbCA8LSBjKCIjMTI3OUI1IiwiIzJEMkQzNyIpCgpQaXRjaF9QUkFBVCA8LSBsaXN0LmZpbGVzKHBhdGggPSBwYXN0ZSgiUHJlcHBlZCBEYXRhL0V4YW1wbGUgRGF0YS8iLCBzZXAgPSAiIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuID0gIi5QaXRjaCIsIGlnbm9yZS5jYXNlID0gVCkgJT4lCiAgICBwYXN0ZSgiUHJlcHBlZCBEYXRhL0V4YW1wbGUgRGF0YS8iLC4sIHNlcCA9ICIiKSAlPiUKICAgIHJlYWQuZGVsaW0oLiwgaGVhZGVyID0gRikgJT4lCiAgICBkcGx5cjo6cmVuYW1lKFBpdGNoID0gVjEpICU+JQogICAgZHBseXI6Om11dGF0ZShQaXRjaCA9IGdzdWIoIi0tdW5kZWZpbmVkLS0iLE5BLFBpdGNoKSwKICAgICAgICAgICAgICAgICAgUGl0Y2ggPSBhcy5udW1lcmljKFBpdGNoKSkKCkZvcm1hbnRzX1BSQUFUIDwtIGxpc3QuZmlsZXMocGF0aCA9IHBhc3RlKCJQcmVwcGVkIERhdGEvRXhhbXBsZSBEYXRhLyIsIHNlcCA9ICIiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiX0Zvcm1hbnQiLCBpZ25vcmUuY2FzZSA9IFQpICU+JQogICAgcGFzdGUoIlByZXBwZWQgRGF0YS9FeGFtcGxlIERhdGEvIiwuLCBzZXAgPSAiIikgJT4lCiAgICByZWFkLmRlbGltKC4sIGhlYWRlciA9IFQpICU+JQogICAgZHBseXI6OnNlbGVjdCghYyhuZm9ybWFudHMsIEIxLkh6LiwgQjIuSHouLCBCMy5Iei4sIEY0Lkh6LiwgQjQuSHouLCBGNS5Iei4sIEI1Lkh6LikpICU+JQogICAgZHBseXI6OnJlbmFtZShUaW1lX3MgPSB0aW1lLnMuLAogICAgICAgICAgICAgICAgICBGMV9IeiA9IEYxLkh6LiwKICAgICAgICAgICAgICAgICAgRjJfSHogPSBGMi5Iei4sCiAgICAgICAgICAgICAgICAgIEYzX0h6ID0gRjMuSHouKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoRjFfSHogPSBpZmVsc2UoRjFfSHogPT0gMCwgTkEsIEYxX0h6KSwKICAgICAgICAgICAgICAgICAgRjJfSHogPSBpZmVsc2UoRjJfSHogPT0gMCwgTkEsIEYyX0h6KSwKICAgICAgICAgICAgICAgICAgRjNfSHogPSBpZmVsc2UoRjNfSHogPT0gMCwgTkEsIEYzX0h6KSkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKEYxX0h6ID0gYXMubnVtZXJpYyhGMV9IeiksCiAgICAgICAgICAgICAgICAgIEYyX0h6ID0gYXMubnVtZXJpYyhGMl9IeiksCiAgICAgICAgICAgICAgICAgIEYzX0h6ID0gc3VwcHJlc3NXYXJuaW5ncyhhcy5udW1lcmljKEYzX0h6KSksCiAgICAgICAgICAgICAgICAgIFRpbWVfbXMgPSBUaW1lX3MgLyAxMDAwLAogICAgICAgICAgICAgICAgICBGMV9rSHogPSBGMV9IeiAvIDEwMDAsCiAgICAgICAgICAgICAgICAgIEYyX2tIeiA9IEYyX0h6IC8gMTAwMCwKICAgICAgICAgICAgICAgICAgRjNfa0h6ID0gRjNfSHogLyAxMDAwLAogICAgICAgICAgICAgICAgICBGMV9iID0gZW11Ujo6YmFyayhGMV9IeiksCiAgICAgICAgICAgICAgICAgIEYyX2IgPSBlbXVSOjpiYXJrKEYyX0h6KSwKICAgICAgICAgICAgICAgICAgRjNfYiA9IGVtdVI6OmJhcmsoRjNfSHopKSAlPiUKICAgIGRwbHlyOjpzZWxlY3QoIVRpbWVfcykgJT4lCiAgICBkcGx5cjo6cmVsb2NhdGUoVGltZV9tcywgLmJlZm9yZSA9IEYxX0h6KSAlPiUKICAgIGNiaW5kKC4sUGl0Y2hfUFJBQVQpCiAgCiAgYyA8LSAyCiAgd2hpbGUoYyA8IE5ST1coRm9ybWFudHNfUFJBQVQpKXsKICAgIEZvcm1hbnRzX1BSQUFUJEYxX0h6W2NdIDwtIGlmZWxzZShpcy5uYShGb3JtYW50c19QUkFBVCRGMV9IeltjLTFdKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMubmEoRm9ybWFudHNfUFJBQVQkRjFfSHpbYysxXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybWFudHNfUFJBQVQkRjFfSHpbY10pCiAgICBGb3JtYW50c19QUkFBVCRGMl9IeltjXSA8LSBpZmVsc2UoaXMubmEoRm9ybWFudHNfUFJBQVQkRjJfSHpbYy0xXSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzLm5hKEZvcm1hbnRzX1BSQUFUJEYyX0h6W2MrMV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcm1hbnRzX1BSQUFUJEYyX0h6W2NdKQogICAgYyA8LSBjICsgMQogIH0KICBybShjKQogIAogICMgUmF3IEZvcm1hbnRzIC0tLS0KICBmMSA8LSBnZ3Bsb3QoYWVzKHg9RjJfYiwKICAgICAgICAgICAgICAgICAgIHk9RjFfYiksCiAgICAgICAgICAgICAgIGRhdGEgPSBGb3JtYW50c19QUkFBVCkgKyAKICAgICAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBjb2xvciA9IG15UGFsWzJdKSArCiAgICAgIHNjYWxlX3lfcmV2ZXJzZSgpICsKICAgICAgc2NhbGVfeF9yZXZlcnNlKCkgKwogICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gbXlQYWwpICsKICAgICAgdGhlbWVfY2xhc3NpYygpICsgbGFicyh0aXRsZSA9IHBhc3RlKCJSYXcgRm9ybWFudCBWYWx1ZXMiKSkgKyB4bGFiKCJGMiAoYmFyaykiKSArIHlsYWIoIkYxIChiYXJrKSIpICsKICAgICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgICAgIGFzcGVjdC5yYXRpbyA9IDEsCiAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpCiAgICAKIyBTdGVwICMxOiBWb2ljZWQgU2VnbWVudHMgLS0tLQogICAgcGxvdERhdGEgPC0gRm9ybWFudHNfUFJBQVQgJT4lCiAgICAgICAgICAgICAgICAgICBkcGx5cjo6bXV0YXRlKGlzT3V0bGllciA9IGNhc2Vfd2hlbigKICAgICAgICAgICAgICAgICAgICAgaXMubmEoUGl0Y2gpIH4gIlJlbW92ZWQiLAogICAgICAgICAgICAgICAgICAgICBUUlVFIH4gIlJldGFpbmVkIgogICAgICAgICAgICAgICAgICAgKSkKICAgIGYyIDwtIGdncGxvdChkYXRhID0gcGxvdERhdGEsCiAgICAgICAgICAgICAgICAgYWVzKHggPSBGMl9iLAogICAgICAgICAgICAgICAgICAgICB5ID0gRjFfYiwKICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBpc091dGxpZXIpKSArIAogICAgICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIGRhdGEgPSBwbG90RGF0YSAlPiUKICAgICAgICAgICAgICAgICAgIGRwbHlyOjpmaWx0ZXIoaXNPdXRsaWVyID09ICJSZW1vdmVkIikpICsKICAgICAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBkYXRhID0gcGxvdERhdGEgJT4lCiAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKGlzT3V0bGllciA9PSAiUmV0YWluZWQiKSkgKwogICAgICBzY2FsZV95X3JldmVyc2UoKSArCiAgICAgIHNjYWxlX3hfcmV2ZXJzZSgpICsKICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IG15UGFsKSArCiAgICAgIHRoZW1lX2NsYXNzaWMoKSArIGxhYnModGl0bGUgPSBwYXN0ZSgiU3RlcCAjMTpcblZvaWNlZCBTZWdtZW50cyIpKSArCiAgICAgIHhsYWIoIkYyIChiYXJrKSIpICsKICAgICAgeWxhYigiRjEgKGJhcmspIikgKwogICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICAgICAgYXNwZWN0LnJhdGlvID0gMSwKICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkKICAgIAojIFN0ZXAgMjogTUFEIC0tLS0KICAgIHBsb3REYXRhIDwtIEZvcm1hbnRzX1BSQUFUICU+JQogICAgICBkcGx5cjo6ZmlsdGVyKCFpcy5uYShQaXRjaCkpICU+JQogICAgICBkcGx5cjo6bXV0YXRlKEYxX21hZCA9IChhYnMoRjFfSHogLSBtZWRpYW4oRjFfSHopKS8gbWFkKEYxX0h6LCBjb25zdGFudCA9IDEuNDgyNikpID4gMi41LAogICAgICAgICAgICAgICAgICAgIEYyX21hZCA9IChhYnMoRjJfSHogLSBtZWRpYW4oRjJfSHopKS8gbWFkKEYyX0h6LCBjb25zdGFudCA9IDEuNDgyNikpID4gMi41LAogICAgICAgICAgICAgICAgICAgIGlzT3V0bGllciA9IGNhc2Vfd2hlbigKICAgICAgICAgICAgICAgICAgICAgIEYxX21hZCA9PSBUUlVFIHwgRjJfbWFkID09IFRSVUUgfiAiUmVtb3ZlZCIsCiAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gIlJldGFpbmVkIgogICAgICAgICAgICAgICApKQogICAgCiAgICBmMyA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3REYXRhLAogICAgICAgICAgICAgICAgIGFlcyh4ID0gRjJfYiwKICAgICAgICAgICAgICAgICAgICAgeSA9IEYxX2IsCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gaXNPdXRsaWVyKSkgKyAKICAgICAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBkYXRhID0gcGxvdERhdGEgJT4lCiAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKGlzT3V0bGllciA9PSAiUmVtb3ZlZCIpKSArCiAgICAgIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgZGF0YSA9IHBsb3REYXRhICU+JQogICAgICAgICAgICAgZHBseXI6OmZpbHRlcihpc091dGxpZXIgPT0gIlJldGFpbmVkIikpICsKICAgICAgc2NhbGVfeV9yZXZlcnNlKCkgKwogICAgICBzY2FsZV94X3JldmVyc2UoKSArCiAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBteVBhbCkgKwogICAgICB0aGVtZV9jbGFzc2ljKCkgKwogICAgICBsYWJzKHRpdGxlID0gcGFzdGUoIlN0ZXAgIzI6XG5NZWRpYW4gQWJzb2x1dGUgRGV2aWF0aW9uIikpICsKICAgICAgeGxhYigiRjIgKGJhcmspIikgKwogICAgICB5bGFiKCJGMSAoYmFyaykiKSArCiAgICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgICAgICAgICBhc3BlY3QucmF0aW8gPSAxLAogICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKQogICAgCiMgU3RlcCAzOiBNYWhhbGFuaG9iaXMgRGlzdGFuY2UgLS0tLQogIHBsb3REYXRhIDwtIEZvcm1hbnRzX1BSQUFUICU+JQogICAgICBkcGx5cjo6ZmlsdGVyKCFpcy5uYShQaXRjaCkpICU+JQogICAgICBkcGx5cjo6bXV0YXRlKEYxX21hZCA9IChhYnMoRjFfSHogLSBtZWRpYW4oRjFfSHopKS8gbWFkKEYxX0h6LCBjb25zdGFudCA9IDEuNDgyNikpID4gMi41LAogICAgICAgICAgICAgICAgICAgIEYyX21hZCA9IChhYnMoRjJfSHogLSBtZWRpYW4oRjJfSHopKS8gbWFkKEYyX0h6LCBjb25zdGFudCA9IDEuNDgyNikpID4gMi41KSAlPiUKICAgICAgZHBseXI6OmZpbHRlcihGMV9tYWQgPT0gRkFMU0UgJiBGMl9tYWQgPT0gRkFMU0UpICU+JQogICAgICBkcGx5cjo6bXV0YXRlKG1EaXN0ID0gbWFoYWxhbm9iaXMoY2JpbmQoLiRGMV9IeiwgLiRGMl9IeiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sTWVhbnMoY2JpbmQoLiRGMV9IeiwgLiRGMl9IeikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdiA9IGNvdihjYmluZCguJEYxX0h6LCAuJEYyX0h6KSkpLAogICAgICAgICAgICAgICAgICBtRGlzdF9zZCA9IGFicyhzY2FsZShtRGlzdCxjZW50ZXIgPSBUKSksCiAgICAgICAgICAgICAgICAgIGlzT3V0bGllciA9IGNhc2Vfd2hlbigKICAgICAgICAgICAgICAgICAgICBtRGlzdF9zZCA8IDIgfiAiUmV0YWluZWQiLAogICAgICAgICAgICAgICAgICAgIFRSVUUgfiAiUmVtb3ZlZCIKICAgICAgICAgICAgICAgICAgKSkKICAgIAogICAgZjQgPC0gZ2dwbG90KGRhdGEgPSBwbG90RGF0YSwKICAgICAgICAgICAgICAgICBhZXMoeCA9IEYyX2IsCiAgICAgICAgICAgICAgICAgICAgIHkgPSBGMV9iLAogICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGlzT3V0bGllcikpICsgCiAgICAgIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgZGF0YSA9IHBsb3REYXRhICU+JQogICAgICAgICAgICAgICAgICAgZHBseXI6OmZpbHRlcihpc091dGxpZXIgPT0gIlJlbW92ZWQiKSkgKwogICAgICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIGRhdGEgPSBwbG90RGF0YSAlPiUKICAgICAgICAgICAgIGRwbHlyOjpmaWx0ZXIoaXNPdXRsaWVyID09ICJSZXRhaW5lZCIpKSArCiAgICAgIHNjYWxlX3lfcmV2ZXJzZSgpICsKICAgICAgc2NhbGVfeF9yZXZlcnNlKCkgKwogICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gbXlQYWwpICsKICAgICAgdGhlbWVfY2xhc3NpYygpICsgbGFicyh0aXRsZSA9IHBhc3RlKCJTdGVwICMzOlxuTWFoYWxhbm9iaXMgRGlzdGFuY2UiKSkgKyB4bGFiKCJGMiAoYmFyaykiKSArIHlsYWIoIkYxIChiYXJrKSIpICsKICAgICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgICAgIGFzcGVjdC5yYXRpbyA9IDEsCiAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpCiAgICAKIyBGaW5hbCBGb3JtYW50cyAtLS0tCiAgICBwbG90RGF0YSA8LSBGb3JtYW50c19QUkFBVCAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKFBpdGNoKSkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKEYxX21hZCA9IChhYnMoRjFfSHogLSBtZWRpYW4oRjFfSHopKS8gbWFkKEYxX0h6LCBjb25zdGFudCA9IDEuNDgyNikpID4gMi41LAogICAgICAgICAgICAgICAgICBGMl9tYWQgPSAoYWJzKEYyX0h6IC0gbWVkaWFuKEYyX0h6KSkvIG1hZChGMl9IeiwgY29uc3RhbnQgPSAxLjQ4MjYpKSA+IDIuNSkgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKEYxX21hZCA9PSBGQUxTRSAmIEYyX21hZCA9PSBGQUxTRSkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKG1EaXN0ID0gbWFoYWxhbm9iaXMoY2JpbmQoLiRGMV9IeiwgLiRGMl9IeiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sTWVhbnMoY2JpbmQoLiRGMV9IeiwgLiRGMl9IeikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdiA9IGNvdihjYmluZCguJEYxX0h6LCAuJEYyX0h6KSkpLAogICAgICAgICAgICAgICAgICBtRGlzdF9zZCA9IGFicyhzY2FsZShtRGlzdCxjZW50ZXIgPSBUKSkpICU+JQogICAgZHBseXI6OmZpbHRlcihtRGlzdF9zZCA8IDIpCiAgICAKICAgIGY1IDwtIGdncGxvdChhZXMoeD1GMl9iLAogICAgICAgICAgICAgICAgICAgICB5PUYxX2IpLAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBwbG90RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSArIAogICAgICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIGNvbG9yID0gbXlQYWxbMl0pICsgCiAgICAgIHNjYWxlX3lfcmV2ZXJzZSgpICsKICAgICAgc2NhbGVfeF9yZXZlcnNlKCkgKwogICAgICB0aGVtZV9jbGFzc2ljKCkgKyBsYWJzKHRpdGxlID0gcGFzdGUoIkZpbmFsIEZvcm1hbnQgVmFsdWVzIikpICsgeGxhYigiRjIgKGJhcmspIikgKyB5bGFiKCJGMSAoYmFyaykiKSArCiAgICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgICAgICAgICBhc3BlY3QucmF0aW8gPSAxLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpCiAgICAKIyBDb21pYmluZyBwbG90cwogICAgZmlsdGVyZWRQbG90IDwtIGYxICsgZjIgKyBmMyArIGY0ICsgZjUgKyBwYXRjaHdvcms6Omd1aWRlX2FyZWEoKSArCiAgICAgIHBhdGNod29yazo6cGxvdF9sYXlvdXQoZ3VpZGVzID0gJ2NvbGxlY3QnLAogICAgICAgICAgICAgICAgICAgICAgICAgbmNvbCA9IDMpCiAgICBmaWx0ZXJlZFBsb3QKICAgIAogICAgZ2dzYXZlKHBsb3QgPSBmaWx0ZXJlZFBsb3QsICJQbG90cy9GaWx0ZXJlZCBGb3JtYW50cy5wbmciLAogICAgICAgICAgIGhlaWdodCA9IDYsCiAgICAgICAgICAgd2lkdGggPSA4LAogICAgICAgICAgIHVuaXRzID0gImluIiwKICAgICAgICAgICBzY2FsZSA9IC45KQogIApgYGAKCiMjIE9UIHZzLiBWQVMKYGBge3J9CnBsb3REYXRhX0ludCA8LSBBY291c3RpY0RhdGEgJT4lCiAgZHBseXI6OmZpbHRlcighZ3JlcGwoIl9yZWwiLCBTcGVha2VyKSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KFNwZWFrZXIpICU+JQogIGRwbHlyOjptdXRhdGUoc2VnTWluID0gYmFzZTo6bWluKFZBUywgdHJhbnNBY2MpLAogICAgICAgICAgICAgICAgc2VnTWF4ID0gYmFzZTo6bWF4KFZBUywgdHJhbnNBY2MpLAogICAgICAgICAgICAgICAgcmF0aW5nQXZnID0gbWVhbihWQVMsIHRyYW5zQWNjLCBuYS5ybSA9IFQpLAogICAgICAgICAgICAgICAgU3BlYWtlciA9IGFzLmZhY3RvcihTcGVha2VyKSwKICAgICAgICAgICAgICAgIEV0aW9sb2d5ID0gYXMuZmFjdG9yKEV0aW9sb2d5KSkgJT4lCiAgYXJyYW5nZShzZWdNYXgpCgpteV9wYWwgPC0gYygiI2YyNjQzMCIsICIjMjcyRDJEIiwiIzI1NmVmZiIpCiMgV2l0aCBhIGJpdCBtb3JlIHN0eWxlCnBsb3RfSW50IDwtIGdncGxvdChwbG90RGF0YV9JbnQpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSBmY3RfaW5vcmRlcihTcGVha2VyKSwKICAgICAgICAgICAgICAgICAgIHhlbmQgPSBTcGVha2VyLAogICAgICAgICAgICAgICAgICAgeSA9IHNlZ01pbiwKICAgICAgICAgICAgICAgICAgIHllbmQgPSBzZWdNYXgsCiAgICAgICAgICAgICAgICAgICBjb2xvciA9IEV0aW9sb2d5KSkgKwogIGdlb21fcG9pbnQoYWVzKHggPSBTcGVha2VyLAogICAgICAgICAgICAgICAgIHkgPSBWQVMsCiAgICAgICAgICAgICAgICAgY29sb3IgPSBFdGlvbG9neSksCiAgICAgICAgICAgICAjY29sb3IgPSBteV9wYWxbMV0sCiAgICAgICAgICAgICBzaXplID0gMywKICAgICAgICAgICAgIHNoYXBlID0gMTkpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gU3BlYWtlciwKICAgICAgICAgICAgICAgICB5ID0gdHJhbnNBY2MsCiAgICAgICAgICAgICAgICAgY29sb3IgPSBFdGlvbG9neSksCiAgICAgICAgICAgICAjY29sb3IgPSBteV9wYWxbMl0sCiAgICAgICAgICAgICBzaXplID0gMywKICAgICAgICAgICAgIHNoYXBlID0gMTUpICsKICBjb29yZF9mbGlwKCkrCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwKICApICsKICB4bGFiKCIiKSArCiAgeWxhYigiU3BlZWNoIEludGVsbGlnaWJpbGl0eSIpICsKICBnZ3RpdGxlKCJTcGVlY2ggSW50ZWxsaWdpYmlsaXR5IikgKwogIHlsaW0oYygwLDEwMCkpCnBsb3RfSW50CgpteVBhbCA8LSBjKCIjMUFBRDc3IiwgIiMxMjc5QjUiLCAiI0ZGQkYwMCIsICIjRkQ3ODUzIiwgIiNCRjMxNzgiKQpteVNoYXBlcyA8LSBjKDE2LCAxOCwgMTcsIDE1KQoKc2NhdHRlcjEgPC0gZ2dwbG90KHBsb3REYXRhX0ludCwKICAgICAgICAgICAgICAgICAgYWVzKHggPSBWQVMsCiAgICAgICAgICAgICAgICAgICAgICB5ID0gdHJhbnNBY2MsCiAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IEV0aW9sb2d5LAogICAgICAgICAgICAgICAgICAgICAgc2hhcGUgPSBFdGlvbG9neSwKICAgICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlID0gRXRpb2xvZ3kpKSArCiAgZ2VvbV9wb2ludCgpICsKICAjZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGKSArCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDAsMTAwKSwgeWxpbSA9IGMoMCwxMDApKSArCiAgbGFicyh4ID0gIkludGVsbGlnaWJpbGl0eSAoVkFTKSIsIHkgPSAiSW50ZWxsaWdpYmlsaXR5IChPVCkiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IG15UGFsKSArCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IG15U2hhcGVzKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShhc3BlY3QucmF0aW89MSwKICAgICAgICBsZWdlbmQucG9zaXRpb249InJpZ2h0IikKCnNjYXR0ZXIyIDwtIGdncGxvdChwbG90RGF0YV9JbnQsCiAgICAgICAgICAgICAgICAgIGFlcyh4ID0gVkFTLAogICAgICAgICAgICAgICAgICAgICAgeSA9IHRyYW5zQWNjLAogICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBFdGlvbG9neSwKICAgICAgICAgICAgICAgICAgICAgIHNoYXBlID0gRXRpb2xvZ3ksCiAgICAgICAgICAgICAgICAgICAgICBsaW5ldHlwZSA9IEV0aW9sb2d5KSkgKwogICNnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRikgKwogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygwLDEwMCksIHlsaW0gPSBjKDAsMTAwKSkgKwogIGxhYnMoeCA9ICJJbnRlbGxpZ2liaWxpdHkgKFZBUykiLCB5ID0gIkludGVsbGlnaWJpbGl0eSAoT1QpIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBteVBhbCkgKwogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBteVNoYXBlcykgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXNwZWN0LnJhdGlvPTEsCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJyaWdodCIpCgpjb21iaW5lZFNjYXR0ZXIgPC0gZ2dhcnJhbmdlKHNjYXR0ZXIxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYXR0ZXIyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1vbi5sZWdlbmQgPSBGLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5jb2wgPSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5yb3cgPSAxKQpjb21iaW5lZFNjYXR0ZXIKCmdnc2F2ZShmaWxlbmFtZSA9ICJQbG90cy9PVCBhbmQgVkFTIFNjYXR0ZXJwbG90LnBuZyIsCiAgICAgICBwbG90ID0gY29tYmluZWRTY2F0dGVyLAogICAgICAgaGVpZ2h0ID0gMiwKICAgICAgIHdpZHRoID0gNiwKICAgICAgIHVuaXRzID0gImluIiwKICAgICAgIHNjYWxlID0gMSkKCnJtKHNjYXR0ZXIxLCBzY2F0dGVyMiwgY29tYmluZWRTY2F0dGVyKQpgYGAKCk1vZGVsIFNjYXR0ZXJwbG90CmBgYHtyfQptb2RlbEZpZ3VyZURhdGEgPC0gQWNvdXN0aWNEYXRhICU+JQogIGRwbHlyOjpmaWx0ZXIoIWdyZXBsKCJfcmVsIixTcGVha2VyKSkgJT4lCiAgZHBseXI6OnNlbGVjdChTcGVha2VyLCBFdGlvbG9neSwgU2V4LCBWU0FfYiwgdm93ZWxfRURfYiwgSHVsbF9iLCBIdWxsX2JWU0RfMjUsIEh1bGxfYlZTRF83NSwgVkFTLCB0cmFuc0FjYykgJT4lCiAgZHBseXI6Om11dGF0ZShTcGVha2VyID0gYXMuZmFjdG9yKFNwZWFrZXIpLAogICAgICAgICAgICAgICAgRXRpb2xvZ3kgPSBhcy5mYWN0b3IoRXRpb2xvZ3kpLAogICAgICAgICAgICAgICAgU2V4ID0gYXMuZmFjdG9yKFNleCkpICU+JQogIHRpZHlyOjpwaXZvdF9sb25nZXIoY29scyA9IFZBUzp0cmFuc0FjYywgbmFtZXNfdG8gPSAiSW50VHlwZSIsIHZhbHVlc190byA9ICJJbnQiKSAlPiUKICBkcGx5cjo6bXV0YXRlKEludFR5cGUgPSBjYXNlX3doZW4oCiAgICBJbnRUeXBlID09ICJ0cmFuc0FjYyIgfiAiT1QiLAogICAgVFJVRSB+ICJWQVMiCiAgKSwKICAgICAgICAgICAgICAgIEludFR5cGUgPSBhcy5mYWN0b3IoSW50VHlwZSkpCgp5bGFiZWwgPC0gIkludGVsbGlnaWJpbGl0eSIKbXlQYWwgPC0gYygiIzJEMkQzNyIsICIjMTI3OUI1IikKbXlQYWxTaGFwZSA8LSBjKDE5LCAxKQoKVlNBIDwtIG1vZGVsRmlndXJlRGF0YSAlPiUKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBWU0FfYiwKICAgICAgeSA9IEludCwKICAgICAgY29sb3IgPSBJbnRUeXBlLAogICAgICBzaGFwZSA9IEludFR5cGUsCiAgICAgIGxpbmV0eXBlID0gSW50VHlwZSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULCBmaWxsID0gImxpZ2h0IGdyZXkiKSArCiAgeGxhYihleHByZXNzaW9uKCJWU0EgKEJhcmsiXjIqIikiKSkgKwogIHlsYWIoeWxhYmVsKSArCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAsMTAwKSkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgYXNwZWN0LnJhdGlvPTEpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gbXlQYWwpICsKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gbXlQYWxTaGFwZSkgKwogIGxhYnMoY29sb3I9IkludGVsbGlnaWJpbGl0eSBUeXBlIiwKICAgICAgIHNoYXBlID0gIkludGVsbGlnaWJpbGl0eSBUeXBlIiwKICAgICAgIGxpbmV0eXBlID0gIkludGVsbGlnaWJpbGl0eSBUeXBlIikKCmRpc3AgPC0gbW9kZWxGaWd1cmVEYXRhICU+JQogIGdncGxvdCgpICsKICBhZXMoeCA9IHZvd2VsX0VEX2IsCiAgICAgIHkgPSBJbnQsCiAgICAgIGNvbG9yID0gSW50VHlwZSwKICAgICAgc2hhcGUgPSBJbnRUeXBlLAogICAgICBsaW5ldHlwZSA9IEludFR5cGUpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVCwgZmlsbCA9ICJsaWdodCBncmV5IikgKwogIHhsYWIoIkNvcm5lciBEaXNwZXJzaW9uIChCYXJrKSIpICsKICB5bGFiKHlsYWJlbCkgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLDEwMCkpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGFzcGVjdC5yYXRpbz0xKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IG15UGFsKSArCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IG15UGFsU2hhcGUpICsKICBsYWJzKGNvbG9yPSJJbnRlbGxpZ2liaWxpdHkgVHlwZSIsCiAgICAgICBzaGFwZSA9ICJJbnRlbGxpZ2liaWxpdHkgVHlwZSIsCiAgICAgICBsaW5ldHlwZSA9ICJJbnRlbGxpZ2liaWxpdHkgVHlwZSIpCgpIdWxsIDwtIG1vZGVsRmlndXJlRGF0YSAlPiUKICBnZ3Bsb3QoKSArCiAgYWVzKHggPSBIdWxsX2IsCiAgICAgIHkgPSBJbnQsCiAgICAgIGNvbG9yID0gSW50VHlwZSwKICAgICAgc2hhcGUgPSBJbnRUeXBlLAogICAgICBsaW5ldHlwZSA9IEludFR5cGUpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVCwgZmlsbCA9ICJsaWdodCBncmV5IikgKwogIHhsYWIoZXhwcmVzc2lvbigiVlNBIltIdWxsXSoiIChCYXJrIl4yKiIpIikpICsKICB5bGFiKHlsYWJlbCkgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLDEwMCkpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGFzcGVjdC5yYXRpbz0xKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBteVBhbCkgKwogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBteVBhbFNoYXBlKSArCiAgbGFicyhjb2xvcj0iSW50ZWxsaWdpYmlsaXR5IFR5cGUiLAogICAgICAgc2hhcGUgPSAiSW50ZWxsaWdpYmlsaXR5IFR5cGUiLAogICAgICAgbGluZXR5cGUgPSAiSW50ZWxsaWdpYmlsaXR5IFR5cGUiKQoKdnNkMjUgPC0gbW9kZWxGaWd1cmVEYXRhICU+JQogIGdncGxvdCgpICsKICBhZXMoeCA9IEh1bGxfYlZTRF8yNSwKICAgICAgeSA9IEludCwKICAgICAgY29sb3IgPSBJbnRUeXBlLAogICAgICBzaGFwZSA9IEludFR5cGUsCiAgICAgIGxpbmV0eXBlID0gSW50VHlwZSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULCBmaWxsID0gImxpZ2h0IGdyZXkiKSArCiAgeGxhYihleHByZXNzaW9uKCJWU0QiWzI1XSoiIChCYXJrIl4yKiIpIikpICsKICB5bGFiKHlsYWJlbCkgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLDEwMCkpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGFzcGVjdC5yYXRpbz0xKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBteVBhbCkgKwogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBteVBhbFNoYXBlKSArCiAgbGFicyhjb2xvcj0iSW50ZWxsaWdpYmlsaXR5IFR5cGUiLAogICAgICAgc2hhcGUgPSAiSW50ZWxsaWdpYmlsaXR5IFR5cGUiLAogICAgICAgbGluZXR5cGUgPSAiSW50ZWxsaWdpYmlsaXR5IFR5cGUiKQoKdnNkNzUgPC0gbW9kZWxGaWd1cmVEYXRhICU+JQogIGdncGxvdCgpICsKICBhZXMoeCA9IEh1bGxfYlZTRF83NSwKICAgICAgeSA9IEludCwKICAgICAgY29sb3IgPSBJbnRUeXBlLAogICAgICBzaGFwZSA9IEludFR5cGUsCiAgICAgIGxpbmV0eXBlID0gSW50VHlwZSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULCBmaWxsID0gImxpZ2h0IGdyZXkiKSArCiAgeGxhYihleHByZXNzaW9uKCJWU0QiWzc1XSoiIChCYXJrIl4yKiIpIikpICsKICB5bGFiKHlsYWJlbCkgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLDEwMCkpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGFzcGVjdC5yYXRpbz0xKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBteVBhbCkgKwogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBteVBhbFNoYXBlKSArCiAgbGFicyhjb2xvcj0iSW50ZWxsaWdpYmlsaXR5IFR5cGUiLAogICAgICAgc2hhcGUgPSAiSW50ZWxsaWdpYmlsaXR5IFR5cGUiLAogICAgICAgbGluZXR5cGUgPSAiSW50ZWxsaWdpYmlsaXR5IFR5cGUiKQoKIyBDcmVhdGluZyBPVCBTY2F0dGVycGxvdCBGaWd1cmUKCnNjYXR0ZXIgPC0gVlNBICsgZGlzcCArIHBhdGNod29yazo6Z3VpZGVfYXJlYSgpICsgSHVsbCArIHZzZDI1ICsgdnNkNzUgKwogIHBhdGNod29yazo6cGxvdF9sYXlvdXQoZ3VpZGVzID0gJ2NvbGxlY3QnLAogICAgICAgICAgICAgICAgICAgICAgICAgbmNvbCA9IDMpCnNjYXR0ZXIgCgpnZ3NhdmUoIlBsb3RzL01vZGVsRmlndXJlLnBuZyIsIHNjYXR0ZXIsCiAgICAgICBoZWlnaHQgPSA0LAogICAgICAgd2lkdGggPSA2LAogICAgICAgdW5pdHMgPSAiaW4iLAogICAgICAgc2NhbGUgPSAxLjEpCmBgYAoKIyBMaXN0ZW5lciBEZW1vZ3JhcGhpYyBJbmZvcm1hdGlvbgpgYGB7cn0KCkxpc3RlbmVyRGVtbyA8LSBMaXN0ZW5lcnMgJT4lCiAgZnVybml0dXJlOjp0YWJsZTEoYWdlLCBnZW5kZXIsIHJhY2UsIGV0aG5pY2l0eSkKCkxpc3RlbmVyRGVtbwoKYGBgCgojIFNwZWFrZXIgRGVtb2dyYXBoaWNzCgpgYGB7cn0KClNwZWFrZXJEZW1vIDwtIEFjb3VzdGljRGF0YSAlPiUKICBkcGx5cjo6c2VsZWN0KGMoU3BlYWtlciwgU2V4LCBFdGlvbG9neSkpCgpBZ2VzIDwtIHJpbzo6aW1wb3J0KCJQcmVwcGVkIERhdGEvU3BlYWtlciBBZ2VzLnhsc3giKQoKU3BlYWtlckRlbW8gPC0gZnVsbF9qb2luKFNwZWFrZXJEZW1vLCBBZ2VzLCBieSA9ICJTcGVha2VyIikKClNwZWFrZXJEZW1vSW5mbyA8LSBTcGVha2VyRGVtbyAlPiUKICBmdXJuaXR1cmU6OnRhYmxlMShTZXgsIEV0aW9sb2d5LCBBZ2UsIG5hLnJtID0gRikKClNwZWFrZXJEZW1vSW5mbwoKU3BlYWtlckRlbW8gJT4lCiAgZHBseXI6OnN1bW1hcml6ZShtZWFuX2FnZSA9IG1lYW4oQWdlLCBuYS5ybSA9IFQpLCBhZ2Vfc2QgPSBzZChBZ2UsIG5hLnJtID0gVCksIGFnZV9yYW5nZSA9IHJhbmdlKEFnZSwgbmEucm0gPSBUKSkKCmBgYAoK